[PATCH v2 1/5] modules: Always have struct mod_tree_root

From: Christophe Leroy
Date: Thu Jan 27 2022 - 06:28:02 EST


In order to separate text and data, we need to setup
two rb trees.

This also means that struct mod_tree_root is required even without
MODULES_TREE_LOOKUP.

Also remove module_addr_min and module_addr_max as there will
be one min and one max for each tree.

Signed-off-by: Christophe Leroy <christophe.leroy@xxxxxxxxxx>
---
kernel/module.c | 39 ++++++++++++++++++---------------------
1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 24dab046e16c..c0f9d63d3f05 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -85,7 +85,7 @@
* Mutex protects:
* 1) List of modules (also safely readable with preempt_disable),
* 2) module_use links,
- * 3) module_addr_min/module_addr_max.
+ * 3) mod_tree.addr_min/mod_tree.addr_max.
* (delete and add uses RCU list operations).
*/
static DEFINE_MUTEX(module_mutex);
@@ -96,6 +96,16 @@ static void do_free_init(struct work_struct *w);
static DECLARE_WORK(init_free_wq, do_free_init);
static LLIST_HEAD(init_free_list);

+static struct mod_tree_root {
+#ifdef CONFIG_MODULES_TREE_LOOKUP
+ struct latch_tree_root root;
+#endif
+ unsigned long addr_min;
+ unsigned long addr_max;
+} mod_tree __cacheline_aligned = {
+ .addr_min = -1UL,
+};
+
#ifdef CONFIG_MODULES_TREE_LOOKUP

/*
@@ -149,17 +159,6 @@ static const struct latch_tree_ops mod_tree_ops = {
.comp = mod_tree_comp,
};

-static struct mod_tree_root {
- struct latch_tree_root root;
- unsigned long addr_min;
- unsigned long addr_max;
-} mod_tree __cacheline_aligned = {
- .addr_min = -1UL,
-};
-
-#define module_addr_min mod_tree.addr_min
-#define module_addr_max mod_tree.addr_max
-
static noinline void __mod_tree_insert(struct mod_tree_node *node)
{
latch_tree_insert(&node->node, &mod_tree.root, &mod_tree_ops);
@@ -209,8 +208,6 @@ static struct module *mod_find(unsigned long addr)

#else /* MODULES_TREE_LOOKUP */

-static unsigned long module_addr_min = -1UL, module_addr_max = 0;
-
static void mod_tree_insert(struct module *mod) { }
static void mod_tree_remove_init(struct module *mod) { }
static void mod_tree_remove(struct module *mod) { }
@@ -239,10 +236,10 @@ static void __mod_update_bounds(void *base, unsigned int size)
unsigned long min = (unsigned long)base;
unsigned long max = min + size;

- if (min < module_addr_min)
- module_addr_min = min;
- if (max > module_addr_max)
- module_addr_max = max;
+ if (min < mod_tree.addr_min)
+ mod_tree.addr_min = min;
+ if (max > mod_tree.addr_max)
+ mod_tree.addr_max = max;
}

static void mod_update_bounds(struct module *mod)
@@ -4546,14 +4543,14 @@ static void cfi_init(struct module *mod)
mod->exit = *exit;
#endif

- cfi_module_add(mod, module_addr_min);
+ cfi_module_add(mod, mod_tree.addr_min);
#endif
}

static void cfi_cleanup(struct module *mod)
{
#ifdef CONFIG_CFI_CLANG
- cfi_module_remove(mod, module_addr_min);
+ cfi_module_remove(mod, mod_tree.addr_min);
#endif
}

@@ -4737,7 +4734,7 @@ struct module *__module_address(unsigned long addr)
{
struct module *mod;

- if (addr < module_addr_min || addr > module_addr_max)
+ if (addr < mod_tree.addr_min || addr > mod_tree.addr_max)
return NULL;

module_assert_mutex_or_preempt();
--
2.33.1