aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2014-06-17 02:15:35 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-06-24 00:05:46 -0400
commitd84e0d69c26b4d739214974d6ad6baf23f510580 (patch)
tree70d4c7e98bd2cab11524d28da6a08dd7f4ad23d0 /arch/powerpc
parentb7b348c682fac04cade7b860c49d4a17f158dad4 (diff)
powerpc/ftrace: Fix nop of modules on 64bit LE (ABIv2)
There is a bug in the handling of the function entry when we are nopping out a branch from a module in ftrace. We compare the result of module_trampoline_target() with the value of ppc_function_entry(), and expect them to be true. But they never will be. module_trampoline_target() will always return the global entry point of the function, whereas ppc_function_entry() will always return the local. Fix it by using the newly added ppc_global_function_entry(). Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/ftrace.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 8fc0c1742498..96efc664b49d 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -105,7 +105,7 @@ __ftrace_make_nop(struct module *mod,
105 struct dyn_ftrace *rec, unsigned long addr) 105 struct dyn_ftrace *rec, unsigned long addr)
106{ 106{
107 unsigned int op; 107 unsigned int op;
108 unsigned long ptr; 108 unsigned long entry, ptr;
109 unsigned long ip = rec->ip; 109 unsigned long ip = rec->ip;
110 void *tramp; 110 void *tramp;
111 111
@@ -136,10 +136,11 @@ __ftrace_make_nop(struct module *mod,
136 136
137 pr_devel("trampoline target %lx", ptr); 137 pr_devel("trampoline target %lx", ptr);
138 138
139 entry = ppc_global_function_entry((void *)addr);
139 /* This should match what was called */ 140 /* This should match what was called */
140 if (ptr != ppc_function_entry((void *)addr)) { 141 if (ptr != entry) {
141 printk(KERN_ERR "addr %lx does not match expected %lx\n", 142 printk(KERN_ERR "addr %lx does not match expected %lx\n",
142 ptr, ppc_function_entry((void *)addr)); 143 ptr, entry);
143 return -EINVAL; 144 return -EINVAL;
144 } 145 }
145 146