[PATCH 1/4] ppc64 FTRACE_WITH_REGS implementation
Implement FTRACE_WITH_REGS for powerpc64, on ELF ABI v2. Initial work started by Vojtech Pavlik, used with permission. * arch/powerpc/kernel/entry_64.S: - enhance _mcount with a stub to test (ftrace_trace_function == &ftrace_stub) as suggested in Documentation/trace/ftrace-design.txt (for reference only, patched out at runtime) - Implement an effective ftrace_caller that works from within the kernel binary as well as from modules. * arch/powerpc/kernel/ftrace.c: - be prepared to deal with ppc64 ELV ABI v2, especially calls to _mcount that result from gcc -mprofile-kernel * arch/powerpc/kernel/module_64.c: - do not save the TOC pointer on the trampoline when the destination is ftrace_caller. This trampoline jump happens from a function prologue before a new stack frame is set up, so bad things may happen otherwise... - relax is_module_trampoline() to recognise the modified trampoline. Signed-off-by: Torsten Duwe -- arch/powerpc/include/asm/ftrace.h |5 + arch/powerpc/kernel/entry_64.S| 112 +++--- arch/powerpc/kernel/ftrace.c | 67 -- arch/powerpc/kernel/module_64.c | 33 ++- 4 files changed, 186 insertions(+), 31 deletions(-) -- diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index e366187..691 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -46,6 +46,8 @@ extern void _mcount(void); #ifdef CONFIG_DYNAMIC_FTRACE +# define FTRACE_ADDR ((unsigned long)ftrace_caller+8) +# define FTRACE_REGS_ADDR FTRACE_ADDR static inline unsigned long ftrace_call_adjust(unsigned long addr) { /* reloction of mcount call site is the same as the address */ @@ -58,6 +60,9 @@ struct dyn_arch_ftrace { #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ +#ifdef CONFIG_DYNAMIC_FTRACE +#define ARCH_SUPPORTS_FTRACE_OPS 1 +#endif #endif #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index d180caf..a4132ef 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -1152,32 +1152,107 @@ _GLOBAL(enter_prom) #ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE -_GLOBAL(mcount) + +#define TOCSAVE 24 + _GLOBAL(_mcount) - blr + nop // REQUIRED for ftrace, to calculate local/global entry diff +.localentry _mcount,.-_mcount + mflrr0 + mtctr r0 + + LOAD_REG_ADDR_PIC(r12,ftrace_trace_function) + ld r12,0(r12) + LOAD_REG_ADDR_PIC(r0,ftrace_stub) + cmpdr0,r12 + ld r0,LRSAVE(r1) + bne-2f + + mtlrr0 + bctr + +2: /* here we have (*ftrace_trace_function)() in r12, + "selfpc" in CTR + and "frompc" in r0 */ + + mtlrr0 + bctr + +_GLOBAL(ftrace_caller) + mr r0,r2 // global (module) call: save module TOC + b 1f +.localentry ftrace_caller,.-ftrace_caller + mr r0,r2 // local call: callee's TOC == our TOC + b 2f + +1: addis r2,r12,(.TOC.-0b)@ha + addir2,r2,(.TOC.-0b)@l + +2: // Here we have our proper TOC ptr in R2, + // and the one we need to restore on return in r0. + + ld r12, 16(r1) // get caller's adress + + stdur1,-SWITCH_FRAME_SIZE(r1) + + std r12, _LINK(r1) + SAVE_8GPRS(0,r1) + std r0,TOCSAVE(r1) + SAVE_8GPRS(8,r1) + SAVE_8GPRS(16,r1) + SAVE_8GPRS(24,r1) + + + LOAD_REG_IMMEDIATE(r3,function_trace_op) + ld r5,0(r3) + + mflrr3 + std r3, _NIP(r1) + std r3, 16(r1) + subir3, r3, MCOUNT_INSN_SIZE + mfmsr r4 + std r4, _MSR(r1) + mfctr r4 + std r4, _CTR(r1) + mfxer r4 + std r4, _XER(r1) + mr r4, r12 + addir6, r1 ,STACK_FRAME_OVERHEAD -_GLOBAL_TOC(ftrace_caller) - /* Taken from output of objdump from lib64/glibc */ - mflrr3 - ld r11, 0(r1) - stdur1, -112(r1) - std r3, 128(r1) - ld r4, 16(r11) - subir3, r3, MCOUNT_INSN_SIZE .globl ftrace_call ftrace_call: bl ftrace_stub nop + + ld r3, _NIP(r1) + mtlrr3 + + REST_8GPRS(0,r1) + REST_8GPRS(8,r1) + REST_8GPRS(16,r1) + REST_8GPRS(24,r1) + + addi r1, r1, SWITCH_FRAME_SIZE + + ld r12, 16(r1) // get caller's adress + mr r2,r0 // restore callee's TOC + mflrr0 // move this LR to CTR + mtctr r0 + mr r0,r12 // restore callee's lr at _mcount site + mtlrr0 + bctr// jump after _mcount site + #ifdef CONFIG_FUNCTION_GRAPH_TRACER .globl ftrace_graph_call
[RESEND PATCH 1/4] ppc64 FTRACE_WITH_REGS implementation
Implement FTRACE_WITH_REGS for powerpc64, on ELF ABI v2. Initial work started by Vojtech Pavlik, used with permission. * arch/powerpc/kernel/entry_64.S: - enhance _mcount with a stub to test (ftrace_trace_function == &ftrace_stub) as suggested in Documentation/trace/ftrace-design.txt (for reference only, patched out at runtime) - Implement an effective ftrace_caller that works from within the kernel binary as well as from modules. * arch/powerpc/kernel/ftrace.c: - be prepared to deal with ppc64 ELV ABI v2, especially calls to _mcount that result from gcc -mprofile-kernel * arch/powerpc/kernel/module_64.c: - do not save the TOC pointer on the trampoline when the destination is ftrace_caller. This trampoline jump happens from a function prologue before a new stack frame is set up, so bad things may happen otherwise... - relax is_module_trampoline() to recognise the modified trampoline. Signed-off-by: Torsten Duwe -- arch/powerpc/include/asm/ftrace.h |5 + arch/powerpc/kernel/entry_64.S| 112 +++--- arch/powerpc/kernel/ftrace.c | 67 -- arch/powerpc/kernel/module_64.c | 33 ++- 4 files changed, 186 insertions(+), 31 deletions(-) -- diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index e366187..691 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -46,6 +46,8 @@ extern void _mcount(void); #ifdef CONFIG_DYNAMIC_FTRACE +# define FTRACE_ADDR ((unsigned long)ftrace_caller+8) +# define FTRACE_REGS_ADDR FTRACE_ADDR static inline unsigned long ftrace_call_adjust(unsigned long addr) { /* reloction of mcount call site is the same as the address */ @@ -58,6 +60,9 @@ struct dyn_arch_ftrace { #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ +#ifdef CONFIG_DYNAMIC_FTRACE +#define ARCH_SUPPORTS_FTRACE_OPS 1 +#endif #endif #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index d180caf..a4132ef 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -1152,32 +1152,107 @@ _GLOBAL(enter_prom) #ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE -_GLOBAL(mcount) + +#define TOCSAVE 24 + _GLOBAL(_mcount) - blr + nop // REQUIRED for ftrace, to calculate local/global entry diff +.localentry _mcount,.-_mcount + mflrr0 + mtctr r0 + + LOAD_REG_ADDR_PIC(r12,ftrace_trace_function) + ld r12,0(r12) + LOAD_REG_ADDR_PIC(r0,ftrace_stub) + cmpdr0,r12 + ld r0,LRSAVE(r1) + bne-2f + + mtlrr0 + bctr + +2: /* here we have (*ftrace_trace_function)() in r12, + "selfpc" in CTR + and "frompc" in r0 */ + + mtlrr0 + bctr + +_GLOBAL(ftrace_caller) + mr r0,r2 // global (module) call: save module TOC + b 1f +.localentry ftrace_caller,.-ftrace_caller + mr r0,r2 // local call: callee's TOC == our TOC + b 2f + +1: addis r2,r12,(.TOC.-0b)@ha + addir2,r2,(.TOC.-0b)@l + +2: // Here we have our proper TOC ptr in R2, + // and the one we need to restore on return in r0. + + ld r12, 16(r1) // get caller's adress + + stdur1,-SWITCH_FRAME_SIZE(r1) + + std r12, _LINK(r1) + SAVE_8GPRS(0,r1) + std r0,TOCSAVE(r1) + SAVE_8GPRS(8,r1) + SAVE_8GPRS(16,r1) + SAVE_8GPRS(24,r1) + + + LOAD_REG_IMMEDIATE(r3,function_trace_op) + ld r5,0(r3) + + mflrr3 + std r3, _NIP(r1) + std r3, 16(r1) + subir3, r3, MCOUNT_INSN_SIZE + mfmsr r4 + std r4, _MSR(r1) + mfctr r4 + std r4, _CTR(r1) + mfxer r4 + std r4, _XER(r1) + mr r4, r12 + addir6, r1 ,STACK_FRAME_OVERHEAD -_GLOBAL_TOC(ftrace_caller) - /* Taken from output of objdump from lib64/glibc */ - mflrr3 - ld r11, 0(r1) - stdur1, -112(r1) - std r3, 128(r1) - ld r4, 16(r11) - subir3, r3, MCOUNT_INSN_SIZE .globl ftrace_call ftrace_call: bl ftrace_stub nop + + ld r3, _NIP(r1) + mtlrr3 + + REST_8GPRS(0,r1) + REST_8GPRS(8,r1) + REST_8GPRS(16,r1) + REST_8GPRS(24,r1) + + addi r1, r1, SWITCH_FRAME_SIZE + + ld r12, 16(r1) // get caller's adress + mr r2,r0 // restore callee's TOC + mflrr0 // move this LR to CTR + mtctr r0 + mr r0,r12 // restore callee's lr at _mcount site + mtlrr0 + bctr// jump after _mcount site + #ifdef CONFIG_FUNCTION_GRAPH_TRACER .globl ftrace_graph_call
Re: [RESEND PATCH 1/4] ppc64 FTRACE_WITH_REGS implementation
On Thu, 18 Jun 2015 18:21:07 +0200 Torsten Duwe wrote: > + > _GLOBAL(ftrace_stub) > + nop > + nop > +.localentry ftrace_stub,.-ftrace_stub You might want to run checkpatch and fix your whitespace errors. -- Steve > blr > #else > _GLOBAL_TOC(_mcount) > @@ -1211,12 +1286,12 @@ _GLOBAL(ftrace_stub) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RESEND PATCH 1/4] ppc64 FTRACE_WITH_REGS implementation
On Thu, Jun 18, 2015 at 12:49:00PM -0400, Steven Rostedt wrote: > On Thu, 18 Jun 2015 18:21:07 +0200 > Torsten Duwe wrote: > > > + > > _GLOBAL(ftrace_stub) > > + nop > > + nop > > +.localentry ftrace_stub,.-ftrace_stub > > You might want to run checkpatch and fix your whitespace errors. Right. Will do. Thanks, Torsten ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RESEND PATCH 1/4] ppc64 FTRACE_WITH_REGS implementation
On Thu, 18 Jun 2015 18:21:07 +0200 Torsten Duwe wrote: > Implement FTRACE_WITH_REGS for powerpc64, on ELF ABI v2. > Initial work started by Vojtech Pavlik, used with permission. > > * arch/powerpc/kernel/entry_64.S: > - enhance _mcount with a stub to test (ftrace_trace_function == > &ftrace_stub) > as suggested in Documentation/trace/ftrace-design.txt > (for reference only, patched out at runtime) > - Implement an effective ftrace_caller that works from within the kernel > binary as well as from modules. > * arch/powerpc/kernel/ftrace.c: > - be prepared to deal with ppc64 ELV ABI v2, especially calls to _mcount > that result from gcc -mprofile-kernel > * arch/powerpc/kernel/module_64.c: > - do not save the TOC pointer on the trampoline when the destination > is ftrace_caller. This trampoline jump happens from a function prologue > before a new stack frame is set up, so bad things may happen > otherwise... > - relax is_module_trampoline() to recognise the modified trampoline. > > Signed-off-by: Torsten Duwe > -- FYI, the standard notation after the change log is '---' not '--'. That way git will chop off this from the change log. When I did a git am -s on this patch I had: Signed-off-by: Torsten Duwe -- arch/powerpc/include/asm/ftrace.h |5 + arch/powerpc/kernel/entry_64.S| 112 +++--- arch/powerpc/kernel/ftrace.c | 67 -- arch/powerpc/kernel/module_64.c | 33 ++- 4 files changed, 186 insertions(+), 31 deletions(-) -- Signed-off-by: Steven Rostedt -- Steve > arch/powerpc/include/asm/ftrace.h |5 + > arch/powerpc/kernel/entry_64.S| 112 > +++--- > arch/powerpc/kernel/ftrace.c | 67 -- > arch/powerpc/kernel/module_64.c | 33 ++- > 4 files changed, 186 insertions(+), 31 deletions(-) > -- > diff --git a/arch/powerpc/include/asm/ftrace.h > b/arch/powerpc/include/asm/ftrace.h > index e366187..691 100644 > --- a/arch/powerpc/include/asm/ftrace.h > +++ b/arch/powerpc/include/asm/ftrace.h ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev