@@ -42,15 +42,47 @@ void __patch_exception(int exc, unsigned long addr);
42
42
} while (0)
43
43
#endif
44
44
45
+ #define OP_RT_RA_MASK 0xffff0000UL
46
+ #define LIS_R2 0x3c020000UL
47
+ #define ADDIS_R2_R12 0x3c4c0000UL
48
+ #define ADDI_R2_R2 0x38420000UL
49
+
45
50
static inline unsigned long ppc_function_entry (void * func )
46
51
{
47
- #ifdef CONFIG_PPC64
52
+ #if defined(CONFIG_PPC64 )
53
+ #if defined(_CALL_ELF ) && _CALL_ELF == 2
54
+ u32 * insn = func ;
55
+
56
+ /*
57
+ * A PPC64 ABIv2 function may have a local and a global entry
58
+ * point. We need to use the local entry point when patching
59
+ * functions, so identify and step over the global entry point
60
+ * sequence.
61
+ *
62
+ * The global entry point sequence is always of the form:
63
+ *
64
+ * addis r2,r12,XXXX
65
+ * addi r2,r2,XXXX
66
+ *
67
+ * A linker optimisation may convert the addis to lis:
68
+ *
69
+ * lis r2,XXXX
70
+ * addi r2,r2,XXXX
71
+ */
72
+ if ((((* insn & OP_RT_RA_MASK ) == ADDIS_R2_R12 ) ||
73
+ ((* insn & OP_RT_RA_MASK ) == LIS_R2 )) &&
74
+ ((* (insn + 1 ) & OP_RT_RA_MASK ) == ADDI_R2_R2 ))
75
+ return (unsigned long )(insn + 2 );
76
+ else
77
+ return (unsigned long )func ;
78
+ #else
48
79
/*
49
- * On PPC64 the function pointer actually points to the function's
50
- * descriptor. The first entry in the descriptor is the address
51
- * of the function text.
80
+ * On PPC64 ABIv1 the function pointer actually points to the
81
+ * function's descriptor. The first entry in the descriptor is the
82
+ * address of the function text.
52
83
*/
53
84
return ((func_descr_t * )func )-> entry ;
85
+ #endif
54
86
#else
55
87
return (unsigned long )func ;
56
88
#endif
0 commit comments