From: Greg Kroah-Hartman Date: Mon, 2 Jun 2014 23:51:33 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.14.6~96 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f804aa77c2f1d7b70e4df6a17fdae13ed2bc088e;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: ftrace-module-hardcode-ftrace_module_init-call-into-load_module.patch --- diff --git a/queue-3.10/ftrace-module-hardcode-ftrace_module_init-call-into-load_module.patch b/queue-3.10/ftrace-module-hardcode-ftrace_module_init-call-into-load_module.patch new file mode 100644 index 00000000000..3311917bc74 --- /dev/null +++ b/queue-3.10/ftrace-module-hardcode-ftrace_module_init-call-into-load_module.patch @@ -0,0 +1,152 @@ +From a949ae560a511fe4e3adf48fa44fefded93e5c2b Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Red Hat)" +Date: Thu, 24 Apr 2014 10:40:12 -0400 +Subject: ftrace/module: Hardcode ftrace_module_init() call into load_module() + +From: "Steven Rostedt (Red Hat)" + +commit a949ae560a511fe4e3adf48fa44fefded93e5c2b upstream. + +A race exists between module loading and enabling of function tracer. + + CPU 1 CPU 2 + ----- ----- + load_module() + module->state = MODULE_STATE_COMING + + register_ftrace_function() + mutex_lock(&ftrace_lock); + ftrace_startup() + update_ftrace_function(); + ftrace_arch_code_modify_prepare() + set_all_module_text_rw(); + + ftrace_arch_code_modify_post_process() + set_all_module_text_ro(); + + [ here all module text is set to RO, + including the module that is + loading!! ] + + blocking_notifier_call_chain(MODULE_STATE_COMING); + ftrace_init_module() + + [ tries to modify code, but it's RO, and fails! + ftrace_bug() is called] + +When this race happens, ftrace_bug() will produces a nasty warning and +all of the function tracing features will be disabled until reboot. + +The simple solution is to treate module load the same way the core +kernel is treated at boot. To hardcode the ftrace function modification +of converting calls to mcount into nops. This is done in init/main.c +there's no reason it could not be done in load_module(). This gives +a better control of the changes and doesn't tie the state of the +module to its notifiers as much. Ftrace is special, it needs to be +treated as such. + +The reason this would work, is that the ftrace_module_init() would be +called while the module is in MODULE_STATE_UNFORMED, which is ignored +by the set_all_module_text_ro() call. + +Link: http://lkml.kernel.org/r/1395637826-3312-1-git-send-email-indou.takao@jp.fujitsu.com + +Reported-by: Takao Indoh +Acked-by: Rusty Russell +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ftrace.h | 2 ++ + kernel/module.c | 3 +++ + kernel/trace/ftrace.c | 27 ++++----------------------- + 3 files changed, 9 insertions(+), 23 deletions(-) + +--- a/include/linux/ftrace.h ++++ b/include/linux/ftrace.h +@@ -524,6 +524,7 @@ static inline int ftrace_modify_call(str + extern int ftrace_arch_read_dyn_info(char *buf, int size); + + extern int skip_trace(unsigned long ip); ++extern void ftrace_module_init(struct module *mod); + + extern void ftrace_disable_daemon(void); + extern void ftrace_enable_daemon(void); +@@ -533,6 +534,7 @@ static inline int ftrace_force_update(vo + static inline void ftrace_disable_daemon(void) { } + static inline void ftrace_enable_daemon(void) { } + static inline void ftrace_release_mod(struct module *mod) {} ++static inline void ftrace_module_init(struct module *mod) {} + static inline int register_ftrace_command(struct ftrace_func_command *cmd) + { + return -EINVAL; +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -3279,6 +3279,9 @@ static int load_module(struct load_info + + dynamic_debug_setup(info->debug, info->num_debug); + ++ /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */ ++ ftrace_module_init(mod); ++ + /* Finally it's fully formed, ready to start executing. */ + err = complete_formation(mod, info); + if (err) +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -4222,16 +4222,11 @@ static void ftrace_init_module(struct mo + ftrace_process_locs(mod, start, end); + } + +-static int ftrace_module_notify_enter(struct notifier_block *self, +- unsigned long val, void *data) ++void ftrace_module_init(struct module *mod) + { +- struct module *mod = data; +- +- if (val == MODULE_STATE_COMING) +- ftrace_init_module(mod, mod->ftrace_callsites, +- mod->ftrace_callsites + +- mod->num_ftrace_callsites); +- return 0; ++ ftrace_init_module(mod, mod->ftrace_callsites, ++ mod->ftrace_callsites + ++ mod->num_ftrace_callsites); + } + + static int ftrace_module_notify_exit(struct notifier_block *self, +@@ -4245,11 +4240,6 @@ static int ftrace_module_notify_exit(str + return 0; + } + #else +-static int ftrace_module_notify_enter(struct notifier_block *self, +- unsigned long val, void *data) +-{ +- return 0; +-} + static int ftrace_module_notify_exit(struct notifier_block *self, + unsigned long val, void *data) + { +@@ -4257,11 +4247,6 @@ static int ftrace_module_notify_exit(str + } + #endif /* CONFIG_MODULES */ + +-struct notifier_block ftrace_module_enter_nb = { +- .notifier_call = ftrace_module_notify_enter, +- .priority = INT_MAX, /* Run before anything that can use kprobes */ +-}; +- + struct notifier_block ftrace_module_exit_nb = { + .notifier_call = ftrace_module_notify_exit, + .priority = INT_MIN, /* Run after anything that can remove kprobes */ +@@ -4298,10 +4283,6 @@ void __init ftrace_init(void) + __start_mcount_loc, + __stop_mcount_loc); + +- ret = register_module_notifier(&ftrace_module_enter_nb); +- if (ret) +- pr_warning("Failed to register trace ftrace module enter notifier\n"); +- + ret = register_module_notifier(&ftrace_module_exit_nb); + if (ret) + pr_warning("Failed to register trace ftrace module exit notifier\n"); diff --git a/queue-3.10/series b/queue-3.10/series index c2948d6c2a8..a50b6d1edc9 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -1,3 +1,4 @@ futex-add-another-early-deadlock-detection-check.patch futex-prevent-attaching-to-kernel-threads.patch mips-dts-fix-missing-device_type-memory-property-in-memory-nodes.patch +ftrace-module-hardcode-ftrace_module_init-call-into-load_module.patch