diff options
Diffstat (limited to 'arch/arm/kernel/ftrace.c')
-rw-r--r-- | arch/arm/kernel/ftrace.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 22f3d6e309f9..76d50e6091bc 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c | |||
@@ -12,9 +12,10 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/ftrace.h> | 14 | #include <linux/ftrace.h> |
15 | |||
15 | #include <asm/cacheflush.h> | 16 | #include <asm/cacheflush.h> |
17 | #include <asm/ftrace.h> | ||
16 | 18 | ||
17 | #define INSN_SIZE 4 | ||
18 | #define PC_OFFSET 8 | 19 | #define PC_OFFSET 8 |
19 | #define BL_OPCODE 0xeb000000 | 20 | #define BL_OPCODE 0xeb000000 |
20 | #define BL_OFFSET_MASK 0x00ffffff | 21 | #define BL_OFFSET_MASK 0x00ffffff |
@@ -32,10 +33,10 @@ unsigned char *ftrace_call_replace(unsigned long pc, unsigned long addr) | |||
32 | { | 33 | { |
33 | long offset; | 34 | long offset; |
34 | 35 | ||
35 | offset = (long)addr - (long)(pc - INSN_SIZE + PC_OFFSET); | 36 | offset = (long)addr - (long)(pc + PC_OFFSET); |
36 | if (unlikely(offset < -33554432 || offset > 33554428)) { | 37 | if (unlikely(offset < -33554432 || offset > 33554428)) { |
37 | /* Can't generate branches that far (from ARM ARM). Ftrace | 38 | /* Can't generate branches that far (from ARM ARM). Ftrace |
38 | * doesn't generate branches outside of core kernel text. | 39 | * doesn't generate branches outside of kernel text. |
39 | */ | 40 | */ |
40 | WARN_ON_ONCE(1); | 41 | WARN_ON_ONCE(1); |
41 | return NULL; | 42 | return NULL; |
@@ -52,7 +53,6 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code, | |||
52 | 53 | ||
53 | old = *(unsigned long *)old_code; | 54 | old = *(unsigned long *)old_code; |
54 | new = *(unsigned long *)new_code; | 55 | new = *(unsigned long *)new_code; |
55 | pc -= INSN_SIZE; | ||
56 | 56 | ||
57 | __asm__ __volatile__ ( | 57 | __asm__ __volatile__ ( |
58 | "1: ldr %1, [%2] \n" | 58 | "1: ldr %1, [%2] \n" |
@@ -77,7 +77,7 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code, | |||
77 | : "memory"); | 77 | : "memory"); |
78 | 78 | ||
79 | if (!err && (replaced == old)) | 79 | if (!err && (replaced == old)) |
80 | flush_icache_range(pc, pc + INSN_SIZE); | 80 | flush_icache_range(pc, pc + MCOUNT_INSN_SIZE); |
81 | 81 | ||
82 | return err; | 82 | return err; |
83 | } | 83 | } |
@@ -89,8 +89,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func) | |||
89 | unsigned char *new; | 89 | unsigned char *new; |
90 | 90 | ||
91 | pc = (unsigned long)&ftrace_call; | 91 | pc = (unsigned long)&ftrace_call; |
92 | pc += INSN_SIZE; | 92 | memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE); |
93 | memcpy(&old, &ftrace_call, INSN_SIZE); | ||
94 | new = ftrace_call_replace(pc, (unsigned long)func); | 93 | new = ftrace_call_replace(pc, (unsigned long)func); |
95 | ret = ftrace_modify_code(pc, (unsigned char *)&old, new); | 94 | ret = ftrace_modify_code(pc, (unsigned char *)&old, new); |
96 | return ret; | 95 | return ret; |
@@ -103,8 +102,7 @@ int ftrace_mcount_set(unsigned long *data) | |||
103 | unsigned char *new; | 102 | unsigned char *new; |
104 | 103 | ||
105 | pc = (unsigned long)&mcount_call; | 104 | pc = (unsigned long)&mcount_call; |
106 | pc += INSN_SIZE; | 105 | memcpy(&old, &mcount_call, MCOUNT_INSN_SIZE); |
107 | memcpy(&old, &mcount_call, INSN_SIZE); | ||
108 | new = ftrace_call_replace(pc, *addr); | 106 | new = ftrace_call_replace(pc, *addr); |
109 | *addr = ftrace_modify_code(pc, (unsigned char *)&old, new); | 107 | *addr = ftrace_modify_code(pc, (unsigned char *)&old, new); |
110 | return 0; | 108 | return 0; |