diff options
Diffstat (limited to 'arch/arm/kernel/ftrace.c')
-rw-r--r-- | arch/arm/kernel/ftrace.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 833c991075a1..5617932a83df 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c | |||
@@ -141,6 +141,15 @@ int ftrace_update_ftrace_func(ftrace_func_t func) | |||
141 | 141 | ||
142 | ret = ftrace_modify_code(pc, 0, new, false); | 142 | ret = ftrace_modify_code(pc, 0, new, false); |
143 | 143 | ||
144 | #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS | ||
145 | if (!ret) { | ||
146 | pc = (unsigned long)&ftrace_regs_call; | ||
147 | new = ftrace_call_replace(pc, (unsigned long)func); | ||
148 | |||
149 | ret = ftrace_modify_code(pc, 0, new, false); | ||
150 | } | ||
151 | #endif | ||
152 | |||
144 | #ifdef CONFIG_OLD_MCOUNT | 153 | #ifdef CONFIG_OLD_MCOUNT |
145 | if (!ret) { | 154 | if (!ret) { |
146 | pc = (unsigned long)&ftrace_call_old; | 155 | pc = (unsigned long)&ftrace_call_old; |
@@ -159,11 +168,29 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
159 | unsigned long ip = rec->ip; | 168 | unsigned long ip = rec->ip; |
160 | 169 | ||
161 | old = ftrace_nop_replace(rec); | 170 | old = ftrace_nop_replace(rec); |
171 | |||
172 | new = ftrace_call_replace(ip, adjust_address(rec, addr)); | ||
173 | |||
174 | return ftrace_modify_code(rec->ip, old, new, true); | ||
175 | } | ||
176 | |||
177 | #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS | ||
178 | |||
179 | int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, | ||
180 | unsigned long addr) | ||
181 | { | ||
182 | unsigned long new, old; | ||
183 | unsigned long ip = rec->ip; | ||
184 | |||
185 | old = ftrace_call_replace(ip, adjust_address(rec, old_addr)); | ||
186 | |||
162 | new = ftrace_call_replace(ip, adjust_address(rec, addr)); | 187 | new = ftrace_call_replace(ip, adjust_address(rec, addr)); |
163 | 188 | ||
164 | return ftrace_modify_code(rec->ip, old, new, true); | 189 | return ftrace_modify_code(rec->ip, old, new, true); |
165 | } | 190 | } |
166 | 191 | ||
192 | #endif | ||
193 | |||
167 | int ftrace_make_nop(struct module *mod, | 194 | int ftrace_make_nop(struct module *mod, |
168 | struct dyn_ftrace *rec, unsigned long addr) | 195 | struct dyn_ftrace *rec, unsigned long addr) |
169 | { | 196 | { |
@@ -231,6 +258,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | |||
231 | extern unsigned long ftrace_graph_call; | 258 | extern unsigned long ftrace_graph_call; |
232 | extern unsigned long ftrace_graph_call_old; | 259 | extern unsigned long ftrace_graph_call_old; |
233 | extern void ftrace_graph_caller_old(void); | 260 | extern void ftrace_graph_caller_old(void); |
261 | extern unsigned long ftrace_graph_regs_call; | ||
262 | extern void ftrace_graph_regs_caller(void); | ||
234 | 263 | ||
235 | static int __ftrace_modify_caller(unsigned long *callsite, | 264 | static int __ftrace_modify_caller(unsigned long *callsite, |
236 | void (*func) (void), bool enable) | 265 | void (*func) (void), bool enable) |
@@ -253,6 +282,14 @@ static int ftrace_modify_graph_caller(bool enable) | |||
253 | ftrace_graph_caller, | 282 | ftrace_graph_caller, |
254 | enable); | 283 | enable); |
255 | 284 | ||
285 | #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS | ||
286 | if (!ret) | ||
287 | ret = __ftrace_modify_caller(&ftrace_graph_regs_call, | ||
288 | ftrace_graph_regs_caller, | ||
289 | enable); | ||
290 | #endif | ||
291 | |||
292 | |||
256 | #ifdef CONFIG_OLD_MCOUNT | 293 | #ifdef CONFIG_OLD_MCOUNT |
257 | if (!ret) | 294 | if (!ret) |
258 | ret = __ftrace_modify_caller(&ftrace_graph_call_old, | 295 | ret = __ftrace_modify_caller(&ftrace_graph_call_old, |