From: Kris Van Hees Date: Thu, 13 Aug 2015 16:23:54 +0000 (-0400) Subject: dtrace: ensure SDT module probes work with NORX X-Git-Tag: v4.1.12-92~303^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=8ba78aab5aa9a55cf673876e49381a38a48864a2;p=users%2Fjedix%2Flinux-maple.git dtrace: ensure SDT module probes work with NORX When the CONFIG_DEBUG_SET_MODULE_RONX option is enabled in the kernel, the executable code of the module is marked read-only prior to calling the module notifier. This causes the patching of NOPs in the probe locations to fail with a system crash. Because patching of SDT probe locations should happen upon module load for DTrace-enabled kernels regardless of whether or not DTrace will be used, it is both cleaner and more correct to make a direct call to the code that handles the patching rather than using the notifier mechanism. The new call takes place prior to marking the pages read-only, avoiding the problem altogether. Orabug: 21630297 Signed-off-by: Kris Van Hees Acked-by: Nick Alcock --- diff --git a/kernel/dtrace/dtrace_sdt.h b/include/linux/dtrace_sdt.h similarity index 91% rename from kernel/dtrace/dtrace_sdt.h rename to include/linux/dtrace_sdt.h index 18a745fc1fc7..90ca2f5c74fe 100644 --- a/kernel/dtrace/dtrace_sdt.h +++ b/include/linux/dtrace_sdt.h @@ -3,6 +3,7 @@ #ifndef _DTRACE_SDT_H_ #define _DTRACE_SDT_H_ +#include #include /* @@ -21,6 +22,7 @@ extern void *dtrace_sdt_probes __attribute__((weak)); extern void dtrace_sdt_init(void); extern void dtrace_sdt_register(struct module *); +extern void dtrace_sdt_register_module(struct module *); extern void dtrace_sdt_exit(void); /* diff --git a/kernel/dtrace/dtrace_os.c b/kernel/dtrace/dtrace_os.c index 415967fd5680..c8076468d709 100644 --- a/kernel/dtrace/dtrace_os.c +++ b/kernel/dtrace/dtrace_os.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,6 @@ #include #include #include -#include "dtrace_sdt.h" #if defined(CONFIG_DT_FASTTRAP) || defined(CONFIG_DT_FASTTRAP_MODULE) # include diff --git a/kernel/dtrace/dtrace_sdt_core.c b/kernel/dtrace/dtrace_sdt_core.c index ce953b85df8e..5e4f189df157 100644 --- a/kernel/dtrace/dtrace_sdt_core.c +++ b/kernel/dtrace/dtrace_sdt_core.c @@ -9,13 +9,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include "dtrace_sdt.h" const char *sdt_prefix = "__dtrace_probe_"; @@ -125,25 +125,14 @@ static int __init nosdt(char *str) early_param("nosdt", nosdt); -static int dtrace_mod_notifier(struct notifier_block *nb, unsigned long val, - void *args) +void dtrace_sdt_register_module(struct module *mp) { - struct module *mp = args; int i, cnt; sdt_probedesc_t *sdp; asm_instr_t **addrs; - /* - * We only need to capture modules in the COMING state, we need a valid - * module structure as argument, and the module needs to actually have - * SDT probes. If not, ignore... - */ - if (val != MODULE_STATE_COMING) - return NOTIFY_DONE; - if (!mp) - return NOTIFY_DONE; if (mp->sdt_probec == 0 || mp->sdt_probes == NULL) - return NOTIFY_DONE; + return; /* * Create a list of addresses (SDT probe locations) that need to be @@ -154,7 +143,7 @@ static int dtrace_mod_notifier(struct notifier_block *nb, unsigned long val, if (addrs == NULL) { pr_warning("%s: cannot allocate SDT probe address list (%s)\n", __func__, mp->name); - return NOTIFY_DONE; + return; } for (i = cnt = 0, sdp = mp->sdt_probes; i < mp->sdt_probec; @@ -178,18 +167,11 @@ static int dtrace_mod_notifier(struct notifier_block *nb, unsigned long val, dtrace_sdt_nop_multi(addrs, cnt); vfree(addrs); - - return NOTIFY_DONE; } -static struct notifier_block dtrace_modfix = { - .notifier_call = dtrace_mod_notifier, -}; - void dtrace_sdt_init(void) { dtrace_sdt_init_arch(); - register_module_notifier(&dtrace_modfix); } #if defined(CONFIG_DT_DT_PERF) || defined(CONFIG_DT_DT_PERF_MODULE) diff --git a/kernel/module.c b/kernel/module.c index be8c504975e8..fb4149f42423 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -3201,6 +3202,8 @@ static int complete_formation(struct module *mod, struct load_info *info) { int err; + dtrace_sdt_register_module(mod); + mutex_lock(&module_mutex); /* Find duplicate symbols (must be called under lock). */