Remove CONFIG_MODULES dependency by flagging out the dependent code. This
allows to use kprobes in a kernel without support for loadable modules,
which is an useful feature for test kernels and embedded kernels.

Cc: linux...@kvack.org
Cc: Andi Kleen <a...@linux.intel.com>
Cc: Masami Hiramatsu <mhira...@kernel.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakki...@linux.intel.com>
---
 arch/Kconfig                |  2 +-
 include/linux/module.h      | 14 +++++------
 kernel/kprobes.c            | 48 +++++++++++++++++++++++--------------
 kernel/trace/trace_kprobe.c | 16 +++++++++++--
 4 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 8cc35dc556c7..e3d6b6868ccb 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -61,7 +61,7 @@ config OPROFILE_NMI_TIMER
 
 config KPROBES
        bool "Kprobes"
-       depends on MODULES
+       depends on MODULES || ARCH_HAS_TEXT_ALLOC
        depends on HAVE_KPROBES
        select KALLSYMS
        help
diff --git a/include/linux/module.h b/include/linux/module.h
index 8850b9692b8f..22c646cff6bd 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -290,6 +290,13 @@ extern typeof(name) __mod_##type##__##name##_device_table  
        \
 
 struct notifier_block;
 
+enum module_state {
+       MODULE_STATE_LIVE,      /* Normal state. */
+       MODULE_STATE_COMING,    /* Full formed, running module_init. */
+       MODULE_STATE_GOING,     /* Going away. */
+       MODULE_STATE_UNFORMED,  /* Still setting it up. */
+};
+
 #ifdef CONFIG_MODULES
 
 extern int modules_disabled; /* for sysctl */
@@ -305,13 +312,6 @@ struct module_use {
        struct module *source, *target;
 };
 
-enum module_state {
-       MODULE_STATE_LIVE,      /* Normal state. */
-       MODULE_STATE_COMING,    /* Full formed, running module_init. */
-       MODULE_STATE_GOING,     /* Going away. */
-       MODULE_STATE_UNFORMED,  /* Still setting it up. */
-};
-
 struct mod_tree_node {
        struct module *mod;
        struct latch_tree_node node;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 611fcda9f6bf..bb2e3070481a 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1617,6 +1617,7 @@ static int check_kprobe_address_safe(struct kprobe *p,
                        goto out;
                }
 
+#ifdef CONFIG_MODULES
                /*
                 * If the module freed .init.text, we couldn't insert
                 * kprobes in there.
@@ -1627,6 +1628,7 @@ static int check_kprobe_address_safe(struct kprobe *p,
                        *probed_mod = NULL;
                        ret = -ENOENT;
                }
+#endif
        }
 out:
        preempt_enable();
@@ -2223,24 +2225,6 @@ int kprobe_add_area_blacklist(unsigned long start, 
unsigned long end)
        return 0;
 }
 
-/* Remove all symbols in given area from kprobe blacklist */
-static void kprobe_remove_area_blacklist(unsigned long start, unsigned long 
end)
-{
-       struct kprobe_blacklist_entry *ent, *n;
-
-       list_for_each_entry_safe(ent, n, &kprobe_blacklist, list) {
-               if (ent->start_addr < start || ent->start_addr >= end)
-                       continue;
-               list_del(&ent->list);
-               kfree(ent);
-       }
-}
-
-static void kprobe_remove_ksym_blacklist(unsigned long entry)
-{
-       kprobe_remove_area_blacklist(entry, entry + 1);
-}
-
 int __init __weak arch_populate_kprobe_blacklist(void)
 {
        return 0;
@@ -2283,6 +2267,25 @@ static int __init populate_kprobe_blacklist(unsigned 
long *start,
        return ret ? : arch_populate_kprobe_blacklist();
 }
 
+#ifdef CONFIG_MODULES
+/* Remove all symbols in given area from kprobe blacklist */
+static void kprobe_remove_area_blacklist(unsigned long start, unsigned long 
end)
+{
+       struct kprobe_blacklist_entry *ent, *n;
+
+       list_for_each_entry_safe(ent, n, &kprobe_blacklist, list) {
+               if (ent->start_addr < start || ent->start_addr >= end)
+                       continue;
+               list_del(&ent->list);
+               kfree(ent);
+       }
+}
+
+static void kprobe_remove_ksym_blacklist(unsigned long entry)
+{
+       kprobe_remove_area_blacklist(entry, entry + 1);
+}
+
 static void add_module_kprobe_blacklist(struct module *mod)
 {
        unsigned long start, end;
@@ -2328,6 +2331,15 @@ static void remove_module_kprobe_blacklist(struct module 
*mod)
                kprobe_remove_area_blacklist(start, end);
        }
 }
+#else
+static void add_module_kprobe_blacklist(struct module *mod)
+{
+}
+
+static void remove_module_kprobe_blacklist(struct module *mod)
+{
+}
+#endif /* CONFIG_MODULES */
 
 /* Module notifier call back, checking kprobes on the module */
 static int kprobes_module_callback(struct notifier_block *nb,
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 710ec6a6aa8f..881c998d0162 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -103,8 +103,9 @@ static nokprobe_inline bool trace_kprobe_has_gone(struct 
trace_kprobe *tk)
        return !!(kprobe_gone(&tk->rp.kp));
 }
 
+#ifdef CONFIG_MODULES
 static nokprobe_inline bool trace_kprobe_within_module(struct trace_kprobe *tk,
-                                                struct module *mod)
+                                                      struct module *mod)
 {
        int len = strlen(mod->name);
        const char *name = trace_kprobe_symbol(tk);
@@ -129,6 +130,17 @@ static nokprobe_inline bool 
trace_kprobe_module_exist(struct trace_kprobe *tk)
 
        return ret;
 }
+#else
+static nokprobe_inline bool trace_kprobe_within_module(struct trace_kprobe *tk,
+                                                      struct module *mod)
+{
+       return false;
+}
+static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk)
+{
+       return false;
+}
+#endif
 
 static bool trace_kprobe_is_busy(struct dyn_event *ev)
 {
@@ -688,7 +700,7 @@ static int trace_kprobe_module_callback(struct 
notifier_block *nb,
                        if (ret)
                                pr_warn("Failed to re-register probe %s on %s: 
%d\n",
                                        trace_probe_name(&tk->tp),
-                                       mod->name, ret);
+                                       module_name(mod), ret);
                }
        }
        mutex_unlock(&event_mutex);
-- 
2.25.1

Reply via email to