Re: [RFC PATCH 4/9] module: Allocate MOD_INIT_TEXT from the MOD_TEXT ROX allocation
From: Bradley Morgan <hidden>
Date: 2026-08-28 14:11:56
Also in:
linux-modules, linux-trace-kernel, lkml
On 22 August 2026 14:53:26 BST, Ard Biesheuvel [off-list ref] wrote:
From: Ard Biesheuvel <ardb@kernel.org> When execmem ROX caches are used for module text and inittext, place them adjacently in memory, by allocating space for both initially, and splitting off the space for MOD_INIT_TEXT as needed. This avoids the corner case on arm64, where .init.text being placed far from .text results in a lot of complexity wrt indirect branches and PLTs that we'd prefer to avoid.
I can't see anything wrong, thanks for the patch Reviewed-by: Bradley Morgan <redacted> # kernel/
quoted hunk ↗ jump to hunk
Signed-off-by: Ard Biesheuvel <ardb@kernel.org> --- kernel/module/main.c | 22 ++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)diff --git a/kernel/module/main.c b/kernel/module/main.c index 46dd8d25a605..2d6213496359 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c@@ -1342,7 +1342,7 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type){ unsigned int size = PAGE_ALIGN(mod->mem[type].size); enum execmem_type execmem_type; - void *ptr; + void *ptr = NULL; mod->mem[type].size = size;@@ -1351,11 +1351,25 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type)else execmem_type = EXECMEM_MODULE_TEXT; - ptr = execmem_alloc_rw(execmem_type, size); + bool is_rox = execmem_is_rox(execmem_type); + if (is_rox) { + /* + * Special case for MOD_TEXT / MOD_INIT_TEXT: allocate the + * latter by splitting off required space from the former + * so that they are always placed close together. + */ + if (type == MOD_TEXT) + size += PAGE_ALIGN(mod->mem[MOD_INIT_TEXT].size); + else if (type == MOD_INIT_TEXT) + ptr = execmem_split(mod->mem[MOD_TEXT].base, size); + } + + if (!ptr) + ptr = execmem_alloc_rw(execmem_type, size); if (!ptr) return -ENOMEM; - mod->mem[type].is_rox = execmem_is_rox(execmem_type); + mod->mem[type].is_rox = is_rox; /* * The pointer to these blocks of memory are stored on the module@@ -1368,7 +1382,7 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type)* *do* eventually get freed, but let's just keep things simple * and avoid *any* false positives. */ - if (!mod->mem[type].is_rox) + if (!is_rox) kmemleak_not_leak(ptr); memset(ptr, 0, size);
--- Thanks!https://lore.kernel.org/all/EE579805-42F2-4C58-B752-F28779EEB717@grrlz.net/ (local)