]> git.itanic.dy.fi Git - linux-stable/commitdiff
next-20240423/modules
authorStephen Rothwell <sfr@canb.auug.org.au>
Wed, 24 Apr 2024 07:31:25 +0000 (17:31 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 24 Apr 2024 07:31:25 +0000 (17:31 +1000)
# Conflicts:
# kernel/module/main.c

1  2 
arch/mips/include/asm/pgtable-64.h
kernel/bpf/core.c
kernel/kprobes.c
kernel/module/main.c
mm/Kconfig
mm/Makefile

Simple merge
Simple merge
Simple merge
index 2d25eebc549dbee1934c45b2a91a38895c316b4a,d56b7df0cbb63fa8ce81c4322fa108c2f0bfbc63..d22ae6ffcb4b30cede00fc7f611150d4675555a4
@@@ -56,8 -56,8 +56,9 @@@
  #include <linux/dynamic_debug.h>
  #include <linux/audit.h>
  #include <linux/cfi.h>
 +#include <linux/codetag.h>
  #include <linux/debugfs.h>
+ #include <linux/execmem.h>
  #include <uapi/linux/module.h>
  #include "internal.h"
  
@@@ -1204,26 -1194,51 +1195,55 @@@ static bool mod_mem_use_vmalloc(enum mo
                mod_mem_type_is_core_data(type);
  }
  
- static void *module_memory_alloc(unsigned int size, enum mod_mem_type type)
+ static int module_memory_alloc(struct module *mod, enum mod_mem_type type)
  {
+       unsigned int size = PAGE_ALIGN(mod->mem[type].size);
+       void *ptr;
+       mod->mem[type].size = size;
        if (mod_mem_use_vmalloc(type))
-               return vzalloc(size);
-       return module_alloc(size);
+               ptr = vmalloc(size);
+       else
+               ptr = execmem_alloc(EXECMEM_MODULE_TEXT, size);
+       if (!ptr)
+               return -ENOMEM;
+       /*
+        * The pointer to these blocks of memory are stored on the module
+        * structure and we keep that around so long as the module is
+        * around. We only free that memory when we unload the module.
+        * Just mark them as not being a leak then. The .init* ELF
+        * sections *do* get freed after boot so we *could* treat them
+        * slightly differently with kmemleak_ignore() and only grey
+        * them out as they work as typical memory allocations which
+        * *do* eventually get freed, but let's just keep things simple
+        * and avoid *any* false positives.
+        */
+       kmemleak_not_leak(ptr);
+       memset(ptr, 0, size);
+       mod->mem[type].base = ptr;
+       return 0;
  }
  
- static void module_memory_free(void *ptr, enum mod_mem_type type,
 -static void module_memory_free(struct module *mod, enum mod_mem_type type)
++static void module_memory_free(struct module *mod, enum mod_mem_type type,
 +                             bool unload_codetags)
  {
+       void *ptr = mod->mem[type].base;
 +      if (!unload_codetags && mod_mem_type_is_core_data(type))
 +              return;
 +
        if (mod_mem_use_vmalloc(type))
                vfree(ptr);
        else
-               module_memfree(ptr);
+               execmem_free(ptr);
  }
  
 -static void free_mod_mem(struct module *mod)
 +static void free_mod_mem(struct module *mod, bool unload_codetags)
  {
        for_each_mod_mem_type(type) {
                struct module_memory *mod_mem = &mod->mem[type];
                /* Free lock-classes; relies on the preceding sync_rcu(). */
                lockdep_free_key_range(mod_mem->base, mod_mem->size);
                if (mod_mem->size)
-                       module_memory_free(mod_mem->base, type,
 -                      module_memory_free(mod, type);
++                      module_memory_free(mod, type,
 +                                         unload_codetags);
        }
  
        /* MOD_DATA hosts mod, so free it at last */
        lockdep_free_key_range(mod->mem[MOD_DATA].base, mod->mem[MOD_DATA].size);
-       module_memory_free(mod->mem[MOD_DATA].base, MOD_DATA, unload_codetags);
 -      module_memory_free(mod, MOD_DATA);
++      module_memory_free(mod, MOD_DATA, unload_codetags);
  }
  
  /* Free a module, remove from lists, etc. */
@@@ -2309,7 -2301,7 +2314,7 @@@ static int move_module(struct module *m
        return 0;
  out_enomem:
        for (t--; t >= 0; t--)
-               module_memory_free(mod->mem[t].base, t, true);
 -              module_memory_free(mod, t);
++              module_memory_free(mod, t, true);
        return ret;
  }
  
diff --cc mm/Kconfig
Simple merge
diff --cc mm/Makefile
Simple merge