aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/ftrace.c')
-rw-r--r--arch/powerpc/kernel/ftrace.c21
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
21static unsigned int ftrace_nop = 0x60000000; 21static 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
30static unsigned int notrace ftrace_calc_offset(long ip, long addr) 31static 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
35notrace unsigned char *ftrace_nop_replace(void) 36notrace 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,
118notrace int ftrace_update_ftrace_func(ftrace_func_t func) 116notrace 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