diff options
Diffstat (limited to 'arch/powerpc/kernel/ftrace.c')
-rw-r--r-- | arch/powerpc/kernel/ftrace.c | 21 |
1 files changed, 7 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index e12c593ab9ca..3855ceb937b0 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c | |||
@@ -15,8 +15,8 @@ | |||
15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
16 | 16 | ||
17 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
18 | #include <asm/ftrace.h> | ||
18 | 19 | ||
19 | #define CALL_BACK 4 | ||
20 | 20 | ||
21 | static unsigned int ftrace_nop = 0x60000000; | 21 | static unsigned int ftrace_nop = 0x60000000; |
22 | 22 | ||
@@ -27,9 +27,10 @@ static unsigned int ftrace_nop = 0x60000000; | |||
27 | # define GET_ADDR(addr) *(unsigned long *)addr | 27 | # define GET_ADDR(addr) *(unsigned long *)addr |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | |||
30 | static unsigned int notrace ftrace_calc_offset(long ip, long addr) | 31 | static unsigned int notrace ftrace_calc_offset(long ip, long addr) |
31 | { | 32 | { |
32 | return (int)((addr + CALL_BACK) - ip); | 33 | return (int)(addr - ip); |
33 | } | 34 | } |
34 | 35 | ||
35 | notrace unsigned char *ftrace_nop_replace(void) | 36 | notrace unsigned char *ftrace_nop_replace(void) |
@@ -76,9 +77,6 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, | |||
76 | unsigned new = *(unsigned *)new_code; | 77 | unsigned new = *(unsigned *)new_code; |
77 | int faulted = 0; | 78 | int faulted = 0; |
78 | 79 | ||
79 | /* move the IP back to the start of the call */ | ||
80 | ip -= CALL_BACK; | ||
81 | |||
82 | /* | 80 | /* |
83 | * Note: Due to modules and __init, code can | 81 | * Note: Due to modules and __init, code can |
84 | * disappear and change, we need to protect against faulting | 82 | * disappear and change, we need to protect against faulting |
@@ -118,12 +116,10 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, | |||
118 | notrace int ftrace_update_ftrace_func(ftrace_func_t func) | 116 | notrace int ftrace_update_ftrace_func(ftrace_func_t func) |
119 | { | 117 | { |
120 | unsigned long ip = (unsigned long)(&ftrace_call); | 118 | unsigned long ip = (unsigned long)(&ftrace_call); |
121 | unsigned char old[4], *new; | 119 | unsigned char old[MCOUNT_INSN_SIZE], *new; |
122 | int ret; | 120 | int ret; |
123 | 121 | ||
124 | ip += CALL_BACK; | 122 | memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); |
125 | |||
126 | memcpy(old, &ftrace_call, 4); | ||
127 | new = ftrace_call_replace(ip, (unsigned long)func); | 123 | new = ftrace_call_replace(ip, (unsigned long)func); |
128 | ret = ftrace_modify_code(ip, old, new); | 124 | ret = ftrace_modify_code(ip, old, new); |
129 | 125 | ||
@@ -134,16 +130,13 @@ notrace int ftrace_mcount_set(unsigned long *data) | |||
134 | { | 130 | { |
135 | unsigned long ip = (long)(&mcount_call); | 131 | unsigned long ip = (long)(&mcount_call); |
136 | unsigned long *addr = data; | 132 | unsigned long *addr = data; |
137 | unsigned char old[4], *new; | 133 | unsigned char old[MCOUNT_INSN_SIZE], *new; |
138 | |||
139 | /* ip is at the location, but modify code will subtact this */ | ||
140 | ip += CALL_BACK; | ||
141 | 134 | ||
142 | /* | 135 | /* |
143 | * Replace the mcount stub with a pointer to the | 136 | * Replace the mcount stub with a pointer to the |
144 | * ip recorder function. | 137 | * ip recorder function. |
145 | */ | 138 | */ |
146 | memcpy(old, &mcount_call, 4); | 139 | memcpy(old, &mcount_call, MCOUNT_INSN_SIZE); |
147 | new = ftrace_call_replace(ip, *addr); | 140 | new = ftrace_call_replace(ip, *addr); |
148 | *addr = ftrace_modify_code(ip, old, new); | 141 | *addr = ftrace_modify_code(ip, old, new); |
149 | 142 | ||