diff options
author | Mark Brown <broonie@kernel.org> | 2021-05-18 17:24:52 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-05-18 17:24:52 +0100 |
commit | c37fe6aff89cb0d842993fe2f69e48bf3ebe0ab0 (patch) | |
tree | 2a322c48218f7006bab789b7bf16ec58b129a096 /arch/powerpc/kernel/module.c | |
parent | d7aed20d446d8c87f5e13adf73281056b0064a45 (diff) | |
parent | d07f6ca923ea0927a1024dfccafc5b53b61cfecc (diff) |
Merge tag 'v5.13-rc2' into spi-5.13
Linux 5.13-rc2
Diffstat (limited to 'arch/powerpc/kernel/module.c')
-rw-r--r-- | arch/powerpc/kernel/module.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index a211b0253cdb..3f35c8d20be7 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -8,12 +8,14 @@ #include <linux/moduleloader.h> #include <linux/err.h> #include <linux/vmalloc.h> +#include <linux/mm.h> #include <linux/bug.h> #include <asm/module.h> #include <linux/uaccess.h> #include <asm/firmware.h> #include <linux/sort.h> #include <asm/setup.h> +#include <asm/sections.h> static LIST_HEAD(module_bug_list); @@ -87,13 +89,36 @@ int module_finalize(const Elf_Ehdr *hdr, return 0; } -#ifdef MODULES_VADDR +static __always_inline void * +__module_alloc(unsigned long size, unsigned long start, unsigned long end) +{ + /* + * Don't do huge page allocations for modules yet until more testing + * is done. STRICT_MODULE_RWX may require extra work to support this + * too. + */ + return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, PAGE_KERNEL_EXEC, + VM_FLUSH_RESET_PERMS | VM_NO_HUGE_VMAP, + NUMA_NO_NODE, __builtin_return_address(0)); +} + void *module_alloc(unsigned long size) { +#ifdef MODULES_VADDR + unsigned long limit = (unsigned long)_etext - SZ_32M; + void *ptr = NULL; + BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR); - return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, GFP_KERNEL, - PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS, NUMA_NO_NODE, - __builtin_return_address(0)); -} + /* First try within 32M limit from _etext to avoid branch trampolines */ + if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit) + ptr = __module_alloc(size, limit, MODULES_END); + + if (!ptr) + ptr = __module_alloc(size, MODULES_VADDR, MODULES_END); + + return ptr; +#else + return __module_alloc(size, VMALLOC_START, VMALLOC_END); #endif +} |