On 22 August 2026 14:53:26 BST, Ard Biesheuvel <[email protected]> wrote:
>From: Ard Biesheuvel <[email protected]>
>
>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 <[email protected]> # kernel/

>Signed-off-by: Ard Biesheuvel <[email protected]>
>---
> 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/[email protected]/

Reply via email to