[PATCH 3/4] powerpc: ftrace: Use create_branch() and cope with errors

Michael Ellerman michael at ellerman.id.au
Thu Jul 17 17:21:32 EST 2008


Use create_branch() rather than doing it by hand. It's possible that
we are unable to create a branch to the address, if it's too far away,
in which case just return a nop. This will break the tracing, but
shouldn't crash the kernel at least.

Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
---
 arch/powerpc/kernel/ftrace.c |   20 ++++++++------------
 1 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 1d6f174..49a2049 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -19,11 +19,6 @@
 #include <asm/ftrace.h>
 
 
-static unsigned int notrace ftrace_calc_offset(long ip, long addr)
-{
-	return (int)(addr - ip);
-}
-
 notrace unsigned char *ftrace_nop_replace(void)
 {
 	static unsigned int ftrace_nop = PPC_NOP_INSTR;
@@ -35,16 +30,17 @@ notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
 {
 	static unsigned int op;
 
-	/*
-	 * It would be nice to just use create_function_call, but that will
-	 * update the code itself. Here we need to just return the
-	 * instruction that is going to be modified, without modifying the
-	 * code.
-	 */
 	addr = ppc_function_entry((void *)addr);
 
 	/* Set to "bl addr" */
-	op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffc);
+	op = create_branch((unsigned int *)ip, addr, BRANCH_SET_LINK);
+
+	/*
+	 * This routine is not allowed to fail, but create_branch() can.
+	 * In that case, just return nop and cross our fingers.
+	 */
+	if (!op)
+		return ftrace_nop_replace();
 
 	/*
 	 * No locking needed, this must be called via kstop_machine
-- 
1.5.5




More information about the Linuxppc-dev mailing list