Skip to content

Commit c93d4f6

Browse files
chleroympe
authored andcommitted
powerpc/ftrace: Add module_trampoline_target() for PPC32
module_trampoline_target() is used by __ftrace_modify_call(). Implement it for PPC32 so that CONFIG_DYNAMIC_FTRACE_WITH_REGS can be activated on PPC32 as well. Signed-off-by: Christophe Leroy <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/42345f464fb465f0fc76f3090e250be8fc1729f0.1635423081.git.christophe.leroy@csgroup.eu
1 parent 88670fd commit c93d4f6

File tree

2 files changed

+29
-33
lines changed

2 files changed

+29
-33
lines changed

arch/powerpc/kernel/module_32.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,31 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
273273
}
274274

275275
#ifdef CONFIG_DYNAMIC_FTRACE
276+
int module_trampoline_target(struct module *mod, unsigned long addr,
277+
unsigned long *target)
278+
{
279+
unsigned int jmp[4];
280+
281+
/* Find where the trampoline jumps to */
282+
if (copy_from_kernel_nofault(jmp, (void *)addr, sizeof(jmp)))
283+
return -EFAULT;
284+
285+
/* verify that this is what we expect it to be */
286+
if ((jmp[0] & 0xffff0000) != PPC_RAW_LIS(_R12, 0) ||
287+
(jmp[1] & 0xffff0000) != PPC_RAW_ADDI(_R12, _R12, 0) ||
288+
jmp[2] != PPC_RAW_MTCTR(_R12) ||
289+
jmp[3] != PPC_RAW_BCTR())
290+
return -EINVAL;
291+
292+
addr = (jmp[1] & 0xffff) | ((jmp[0] & 0xffff) << 16);
293+
if (addr & 0x8000)
294+
addr -= 0x10000;
295+
296+
*target = addr;
297+
298+
return 0;
299+
}
300+
276301
int module_finalize_ftrace(struct module *module, const Elf_Shdr *sechdrs)
277302
{
278303
module->arch.tramp = do_plt_call(module->core_layout.base,

arch/powerpc/kernel/trace/ftrace.c

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,8 @@ __ftrace_make_nop(struct module *mod,
222222
struct dyn_ftrace *rec, unsigned long addr)
223223
{
224224
struct ppc_inst op;
225-
unsigned int jmp[4];
226225
unsigned long ip = rec->ip;
227-
unsigned long tramp;
226+
unsigned long tramp, ptr;
228227

229228
if (copy_from_kernel_nofault(&op, (void *)ip, MCOUNT_INSN_SIZE))
230229
return -EFAULT;
@@ -238,41 +237,13 @@ __ftrace_make_nop(struct module *mod,
238237
/* lets find where the pointer goes */
239238
tramp = find_bl_target(ip, op);
240239

241-
/*
242-
* On PPC32 the trampoline looks like:
243-
* 0x3d, 0x80, 0x00, 0x00 lis r12,sym@ha
244-
* 0x39, 0x8c, 0x00, 0x00 addi r12,r12,sym@l
245-
* 0x7d, 0x89, 0x03, 0xa6 mtctr r12
246-
* 0x4e, 0x80, 0x04, 0x20 bctr
247-
*/
248-
249-
pr_devel("ip:%lx jumps to %lx", ip, tramp);
250-
251240
/* Find where the trampoline jumps to */
252-
if (copy_from_kernel_nofault(jmp, (void *)tramp, sizeof(jmp))) {
253-
pr_err("Failed to read %lx\n", tramp);
241+
if (module_trampoline_target(mod, tramp, &ptr)) {
242+
pr_err("Failed to get trampoline target\n");
254243
return -EFAULT;
255244
}
256245

257-
pr_devel(" %08x %08x ", jmp[0], jmp[1]);
258-
259-
/* verify that this is what we expect it to be */
260-
if (((jmp[0] & 0xffff0000) != 0x3d800000) ||
261-
((jmp[1] & 0xffff0000) != 0x398c0000) ||
262-
(jmp[2] != 0x7d8903a6) ||
263-
(jmp[3] != 0x4e800420)) {
264-
pr_err("Not a trampoline\n");
265-
return -EINVAL;
266-
}
267-
268-
tramp = (jmp[1] & 0xffff) |
269-
((jmp[0] & 0xffff) << 16);
270-
if (tramp & 0x8000)
271-
tramp -= 0x10000;
272-
273-
pr_devel(" %lx ", tramp);
274-
275-
if (tramp != addr) {
246+
if (ptr != addr) {
276247
pr_err("Trampoline location %08lx does not match addr\n",
277248
tramp);
278249
return -EINVAL;

0 commit comments

Comments
 (0)