diff options
-rw-r--r-- | include/linux/ftrace.h | 3 | ||||
-rw-r--r-- | kernel/trace/ftrace.c | 28 |
2 files changed, 31 insertions, 0 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 677432b9cb7..fdb2a89ae54 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -99,6 +99,9 @@ stack_trace_sysctl(struct ctl_table *table, int write, /* asm/ftrace.h must be defined for archs supporting dynamic ftrace */ #include <asm/ftrace.h> +int ftrace_arch_code_modify_prepare(void); +int ftrace_arch_code_modify_post_process(void); + enum { FTRACE_FL_FREE = (1 << 0), FTRACE_FL_FAILED = (1 << 1), diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index fdf913dfc7e..72316d9647b 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -585,6 +585,24 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) return 1; } +/* + * archs can override this function if they must do something + * before the modifying code is performed. + */ +int __weak ftrace_arch_code_modify_prepare(void) +{ + return 0; +} + +/* + * archs can override this function if they must do something + * after the modifying code is performed. + */ +int __weak ftrace_arch_code_modify_post_process(void) +{ + return 0; +} + static int __ftrace_modify_code(void *data) { int *command = data; @@ -607,7 +625,17 @@ static int __ftrace_modify_code(void *data) static void ftrace_run_update_code(int command) { + int ret; + + ret = ftrace_arch_code_modify_prepare(); + FTRACE_WARN_ON(ret); + if (ret) + return; + stop_machine(__ftrace_modify_code, &command, NULL); + + ret = ftrace_arch_code_modify_post_process(); + FTRACE_WARN_ON(ret); } static ftrace_func_t saved_ftrace_func; |