[PATCH 04/13] livepatch: move klp_find_object_module to module.c

From: Christoph Hellwig
Date: Thu Jan 21 2021 - 15:13:23 EST


To uncouple the livepatch code from module loader internals move a
slightly refactored version of klp_find_object_module to module.c
This allows to mark find_module static and removes one of the last
users of module_mutex outside of module.c.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
include/linux/module.h | 3 +--
kernel/livepatch/core.c | 39 +++++++++++++--------------------------
kernel/module.c | 17 ++++++++++++++++-
3 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index b4654f8a408134..8588482bde4116 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -586,8 +586,7 @@ static inline bool within_module(unsigned long addr, const struct module *mod)
return within_module_init(addr, mod) || within_module_core(addr, mod);
}

-/* Search for module by name: must hold module_mutex. */
-struct module *find_module(const char *name);
+struct module *find_klp_module(const char *name);

/* Check if a module is loaded. */
bool module_loaded(const char *name);
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index a7f625dc24add3..878759baadd81c 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -49,30 +49,6 @@ static bool klp_is_module(struct klp_object *obj)
return obj->name;
}

-/* sets obj->mod if object is not vmlinux and module is found */
-static void klp_find_object_module(struct klp_object *obj)
-{
- struct module *mod;
-
- mutex_lock(&module_mutex);
- /*
- * We do not want to block removal of patched modules and therefore
- * we do not take a reference here. The patches are removed by
- * klp_module_going() instead.
- */
- mod = find_module(obj->name);
- /*
- * Do not mess work of klp_module_coming() and klp_module_going().
- * Note that the patch might still be needed before klp_module_going()
- * is called. Module functions can be called even in the GOING state
- * until mod->exit() finishes. This is especially important for
- * patches that modify semantic of the functions.
- */
- if (mod && mod->klp_alive)
- obj->mod = mod;
- mutex_unlock(&module_mutex);
-}
-
static bool klp_initialized(void)
{
return !!klp_root_kobj;
@@ -820,14 +796,25 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
const char *name;

obj->patched = false;
- obj->mod = NULL;

if (klp_is_module(obj)) {
if (strlen(obj->name) >= MODULE_NAME_LEN)
return -EINVAL;
name = obj->name;

- klp_find_object_module(obj);
+ /*
+ * We do not want to block removal of patched modules and
+ * therefore we do not take a reference here. The patches are
+ * removed by klp_module_going() instead.
+ *
+ * Do not mess work of klp_module_coming() and
+ * klp_module_going(). Note that the patch might still be
+ * needed before klp_module_going() is called. Module functions
+ * can be called even in the GOING state until mod->exit()
+ * finishes. This is especially important for patches that
+ * modify semantic of the functions.
+ */
+ obj->mod = find_klp_module(obj->name);
} else {
name = "vmlinux";
}
diff --git a/kernel/module.c b/kernel/module.c
index 619ea682e64cd1..299cbac0775cf2 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -666,7 +666,7 @@ static struct module *find_module_all(const char *name, size_t len,
return NULL;
}

-struct module *find_module(const char *name)
+static struct module *find_module(const char *name)
{
module_assert_mutex();
return find_module_all(name, strlen(name), false);
@@ -684,6 +684,21 @@ bool module_loaded(const char *name)
}
EXPORT_SYMBOL_GPL(module_loaded);

+#ifdef CONFIG_LIVEPATCH
+struct module *find_klp_module(const char *name)
+{
+ struct module *mod;
+
+ mutex_lock(&module_mutex);
+ mod = find_module(name);
+ if (mod && !mod->klp_alive)
+ mod = NULL;
+ mutex_unlock(&module_mutex);
+
+ return mod;
+}
+#endif /* CONFIG_LIVEPATCH */
+
#ifdef CONFIG_SMP

static inline void __percpu *mod_percpu(struct module *mod)
--
2.29.2