Currently, ftrace_graph_caller() sets up a separate stack frame to save some state before calling into prepare_ftrace_return(). Eliminate this by calling into ftrace_graph_caller() right after the ftrace handler.
We make a few changes to accommodate this: 1. Currently, due to where it is present, ftrace_graph_caller() is not invoked if the NIP is modified by the ftrace handler, indicating either a livepatched function or a jprobe'd function. To achieve the same behavior, we now save/compare against original NIP if function graph is enabled, in addition to CONFIG_LIVEPATCH. 2. We use r14 for saving the original NIP and r15 for storing the possibly modified NIP. r15 is later used to determine if the function has been livepatched. 3. To re-use the same stack frame setup/teardown code, we have ftrace_graph_caller() save the modified LR in pt_regs. Signed-off-by: Naveen N. Rao <naveen.n....@linux.vnet.ibm.com> --- arch/powerpc/kernel/trace/ftrace_64_mprofile.S | 70 ++++++++------------------ 1 file changed, 21 insertions(+), 49 deletions(-) diff --git a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S index b1bad68ea6db..981b99dc3029 100644 --- a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S +++ b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S @@ -72,9 +72,10 @@ _GLOBAL(ftrace_caller) addi r3,r3,function_trace_op@toc@l ld r5,0(r3) -#ifdef CONFIG_LIVEPATCH +#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_LIVEPATCH) mr r14,r7 /* remember old NIP */ #endif + /* Calculate ip from nip-4 into r3 for call below */ subi r3, r7, MCOUNT_INSN_SIZE @@ -97,10 +98,19 @@ ftrace_call: nop /* Load ctr with the possibly modified NIP */ - ld r3, _NIP(r1) - mtctr r3 + ld r15, _NIP(r1) + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +.globl ftrace_graph_call +ftrace_graph_call: + b ftrace_graph_stub +_GLOBAL(ftrace_graph_stub) +#endif + + mtctr r15 + #ifdef CONFIG_LIVEPATCH - cmpd r14,r3 /* has NIP been altered? */ + cmpd r14, r15 /* has NIP been altered? */ #endif /* Restore gprs */ @@ -124,13 +134,6 @@ ftrace_call: bne- livepatch_handler #endif -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -.globl ftrace_graph_call -ftrace_graph_call: - b ftrace_graph_stub -_GLOBAL(ftrace_graph_stub) -#endif - bctr /* jump after _mcount site */ _GLOBAL(ftrace_stub) @@ -233,50 +236,19 @@ livepatch_handler: #ifdef CONFIG_FUNCTION_GRAPH_TRACER _GLOBAL(ftrace_graph_caller) - stdu r1, -112(r1) - /* with -mprofile-kernel, parameter regs are still alive at _mcount */ - std r10, 104(r1) - std r9, 96(r1) - std r8, 88(r1) - std r7, 80(r1) - std r6, 72(r1) - std r5, 64(r1) - std r4, 56(r1) - std r3, 48(r1) + cmpd r14, r15 /* has NIP been altered? */ + bne- ftrace_graph_stub - /* Save callee's TOC in the ABI compliant location */ - std r2, 24(r1) - ld r2, PACATOC(r13) /* get kernel TOC in r2 */ - - mfctr r4 /* ftrace_caller has moved local addr here */ - std r4, 40(r1) - mflr r3 /* ftrace_caller has restored LR from stack */ - subi r4, r4, MCOUNT_INSN_SIZE + ld r3, _LINK(r1) + subi r4, r14, MCOUNT_INSN_SIZE /* load saved original NIP */ bl prepare_ftrace_return nop /* * prepare_ftrace_return gives us the address we divert to. - * Change the LR to this. + * We save it in pt_regs to be used when we go back. */ - mtlr r3 - - ld r0, 40(r1) - mtctr r0 - ld r10, 104(r1) - ld r9, 96(r1) - ld r8, 88(r1) - ld r7, 80(r1) - ld r6, 72(r1) - ld r5, 64(r1) - ld r4, 56(r1) - ld r3, 48(r1) - - /* Restore callee's TOC */ - ld r2, 24(r1) - - addi r1, r1, 112 - mflr r0 - bctr + std r3, _LINK(r1) + b ftrace_graph_stub #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -- 2.12.2