diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/ftrace.h | 8 | ||||
-rw-r--r-- | arch/x86/kernel/ftrace.c | 29 |
2 files changed, 34 insertions, 3 deletions
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index 9b6a1fa19e70..2bb43b433e07 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h | |||
@@ -17,6 +17,14 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) | |||
17 | */ | 17 | */ |
18 | return addr - 1; | 18 | return addr - 1; |
19 | } | 19 | } |
20 | |||
21 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
22 | |||
23 | struct dyn_arch_ftrace { | ||
24 | /* No extra data needed for x86 */ | ||
25 | }; | ||
26 | |||
27 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
20 | #endif /* __ASSEMBLY__ */ | 28 | #endif /* __ASSEMBLY__ */ |
21 | #endif /* CONFIG_FUNCTION_TRACER */ | 29 | #endif /* CONFIG_FUNCTION_TRACER */ |
22 | 30 | ||
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index fe832738e1e2..762222ad1387 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -166,7 +166,7 @@ static int ftrace_calc_offset(long ip, long addr) | |||
166 | return (int)(addr - ip); | 166 | return (int)(addr - ip); |
167 | } | 167 | } |
168 | 168 | ||
169 | unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) | 169 | static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) |
170 | { | 170 | { |
171 | static union ftrace_code_union calc; | 171 | static union ftrace_code_union calc; |
172 | 172 | ||
@@ -311,12 +311,12 @@ do_ftrace_mod_code(unsigned long ip, void *new_code) | |||
311 | 311 | ||
312 | static unsigned char ftrace_nop[MCOUNT_INSN_SIZE]; | 312 | static unsigned char ftrace_nop[MCOUNT_INSN_SIZE]; |
313 | 313 | ||
314 | unsigned char *ftrace_nop_replace(void) | 314 | static unsigned char *ftrace_nop_replace(void) |
315 | { | 315 | { |
316 | return ftrace_nop; | 316 | return ftrace_nop; |
317 | } | 317 | } |
318 | 318 | ||
319 | int | 319 | static int |
320 | ftrace_modify_code(unsigned long ip, unsigned char *old_code, | 320 | ftrace_modify_code(unsigned long ip, unsigned char *old_code, |
321 | unsigned char *new_code) | 321 | unsigned char *new_code) |
322 | { | 322 | { |
@@ -349,6 +349,29 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, | |||
349 | return 0; | 349 | return 0; |
350 | } | 350 | } |
351 | 351 | ||
352 | int ftrace_make_nop(struct module *mod, | ||
353 | struct dyn_ftrace *rec, unsigned long addr) | ||
354 | { | ||
355 | unsigned char *new, *old; | ||
356 | unsigned long ip = rec->ip; | ||
357 | |||
358 | old = ftrace_call_replace(ip, addr); | ||
359 | new = ftrace_nop_replace(); | ||
360 | |||
361 | return ftrace_modify_code(rec->ip, old, new); | ||
362 | } | ||
363 | |||
364 | int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | ||
365 | { | ||
366 | unsigned char *new, *old; | ||
367 | unsigned long ip = rec->ip; | ||
368 | |||
369 | old = ftrace_nop_replace(); | ||
370 | new = ftrace_call_replace(ip, addr); | ||
371 | |||
372 | return ftrace_modify_code(rec->ip, old, new); | ||
373 | } | ||
374 | |||
352 | int ftrace_update_ftrace_func(ftrace_func_t func) | 375 | int ftrace_update_ftrace_func(ftrace_func_t func) |
353 | { | 376 | { |
354 | unsigned long ip = (unsigned long)(&ftrace_call); | 377 | unsigned long ip = (unsigned long)(&ftrace_call); |