tile: ftrace: fix function_graph tracer issues
authorTony Lu <zlu@ezchip.com>
Fri, 27 Mar 2015 18:46:38 +0000 (14:46 -0400)
committerChris Metcalf <cmetcalf@ezchip.com>
Fri, 17 Apr 2015 18:01:38 +0000 (14:01 -0400)
- Add support for ARCH_SUPPORTS_FTRACE_OPS
- Replace the instruction in ftrace_call with the bundle {move r10, lr;
jal ftrace_stub}, so that the lr contains the right value after returning
from ftrace_stub.  An alternative fix might be to leave the instruction
in ftrace_call alone when it is being updated with ftrace_stub.

Signed-off-by: Tony Lu <zlu@ezchip.com>
Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
arch/tile/include/asm/ftrace.h
arch/tile/kernel/ftrace.c
arch/tile/kernel/mcount_64.S

index 13a9bb81a8ab4754ff93da4c8f17da8a134ce4ec..738d239b792f0aab7a974f75600bd7adad676b4f 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef __ASSEMBLY__
 extern void __mcount(void);
 
+#define ARCH_SUPPORTS_FTRACE_OPS 1
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 static inline unsigned long ftrace_call_adjust(unsigned long addr)
 {
index 8d52d83cc51617b8d8e055dba3672cdcbdd46f3a..0c0996175b1ed613cf6fe4d3e89cec85ea5c6a6f 100644 (file)
@@ -74,7 +74,11 @@ static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
                        create_JumpOff_X1(pcrel_by_instr);
        }
 
-       if (addr == FTRACE_ADDR) {
+       /*
+        * Also put { move r10, lr; jal ftrace_stub } in a bundle, which
+        * is used to replace the instruction in address ftrace_call.
+        */
+       if (addr == FTRACE_ADDR || addr == (unsigned long)ftrace_stub) {
                /* opcode: or r10, lr, zero */
                opcode_x0 =
                        create_Dest_X0(10) |
index 3c2b8d5e1d1a02feb744da440a3bab224b125d6d..6c6702451962360cefa822f403c18628a31bb2e7 100644 (file)
@@ -81,7 +81,12 @@ STD_ENTRY(ftrace_caller)
 
        /* arg1: self return address */
        /* arg2: parent's return address */
-       { move  r0, lr; move    r1, r10 }
+       /* arg3: ftrace_ops */
+       /* arg4: regs (but make it NULL) */
+       { move  r0, lr;  moveli        r2, hw2_last(function_trace_op) }
+       { move  r1, r10; shl16insli    r2, r2, hw1(function_trace_op) }
+       { movei r3, 0;   shl16insli    r2, r2, hw0(function_trace_op) }
+       ld      r2,r2
 
        .global ftrace_call
 ftrace_call: