[PATCH 5/8] powerpc/ftrace: Eliminate duplicate stack setup for ftrace_graph_caller()

Naveen N. Rao naveen.n.rao at linux.vnet.ibm.com
Thu May 4 14:36:18 AEST 2017


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.rao at 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 at 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



More information about the Linuxppc-dev mailing list