diff options
author | Tony Lu <zlu@ezchip.com> | 2015-03-27 14:46:38 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@ezchip.com> | 2015-04-17 14:01:38 -0400 |
commit | 437d3e124d25daaa671bfecfd4015ecd2503a955 (patch) | |
tree | ddc6e9491b9a14a09c6476d0543e9f4896dfd77d /arch/tile | |
parent | a84f24230c137a4e0ab14185e9175798ca1b0376 (diff) |
tile: ftrace: fix function_graph tracer issues
- 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>
Diffstat (limited to 'arch/tile')
-rw-r--r-- | arch/tile/include/asm/ftrace.h | 2 | ||||
-rw-r--r-- | arch/tile/kernel/ftrace.c | 6 | ||||
-rw-r--r-- | arch/tile/kernel/mcount_64.S | 7 |
3 files changed, 13 insertions, 2 deletions
diff --git a/arch/tile/include/asm/ftrace.h b/arch/tile/include/asm/ftrace.h index 13a9bb81a8ab..738d239b792f 100644 --- a/arch/tile/include/asm/ftrace.h +++ b/arch/tile/include/asm/ftrace.h | |||
@@ -23,6 +23,8 @@ | |||
23 | #ifndef __ASSEMBLY__ | 23 | #ifndef __ASSEMBLY__ |
24 | extern void __mcount(void); | 24 | extern void __mcount(void); |
25 | 25 | ||
26 | #define ARCH_SUPPORTS_FTRACE_OPS 1 | ||
27 | |||
26 | #ifdef CONFIG_DYNAMIC_FTRACE | 28 | #ifdef CONFIG_DYNAMIC_FTRACE |
27 | static inline unsigned long ftrace_call_adjust(unsigned long addr) | 29 | static inline unsigned long ftrace_call_adjust(unsigned long addr) |
28 | { | 30 | { |
diff --git a/arch/tile/kernel/ftrace.c b/arch/tile/kernel/ftrace.c index 8d52d83cc516..0c0996175b1e 100644 --- a/arch/tile/kernel/ftrace.c +++ b/arch/tile/kernel/ftrace.c | |||
@@ -74,7 +74,11 @@ static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr, | |||
74 | create_JumpOff_X1(pcrel_by_instr); | 74 | create_JumpOff_X1(pcrel_by_instr); |
75 | } | 75 | } |
76 | 76 | ||
77 | if (addr == FTRACE_ADDR) { | 77 | /* |
78 | * Also put { move r10, lr; jal ftrace_stub } in a bundle, which | ||
79 | * is used to replace the instruction in address ftrace_call. | ||
80 | */ | ||
81 | if (addr == FTRACE_ADDR || addr == (unsigned long)ftrace_stub) { | ||
78 | /* opcode: or r10, lr, zero */ | 82 | /* opcode: or r10, lr, zero */ |
79 | opcode_x0 = | 83 | opcode_x0 = |
80 | create_Dest_X0(10) | | 84 | create_Dest_X0(10) | |
diff --git a/arch/tile/kernel/mcount_64.S b/arch/tile/kernel/mcount_64.S index 3c2b8d5e1d1a..6c6702451962 100644 --- a/arch/tile/kernel/mcount_64.S +++ b/arch/tile/kernel/mcount_64.S | |||
@@ -81,7 +81,12 @@ STD_ENTRY(ftrace_caller) | |||
81 | 81 | ||
82 | /* arg1: self return address */ | 82 | /* arg1: self return address */ |
83 | /* arg2: parent's return address */ | 83 | /* arg2: parent's return address */ |
84 | { move r0, lr; move r1, r10 } | 84 | /* arg3: ftrace_ops */ |
85 | /* arg4: regs (but make it NULL) */ | ||
86 | { move r0, lr; moveli r2, hw2_last(function_trace_op) } | ||
87 | { move r1, r10; shl16insli r2, r2, hw1(function_trace_op) } | ||
88 | { movei r3, 0; shl16insli r2, r2, hw0(function_trace_op) } | ||
89 | ld r2,r2 | ||
85 | 90 | ||
86 | .global ftrace_call | 91 | .global ftrace_call |
87 | ftrace_call: | 92 | ftrace_call: |