From a9c0f28951fd1f8d618506514ec5270305795479 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 14 Apr 2025 18:34:10 +0200 Subject: [PATCH] generic: 6.12: move MIPS reloc patch from pending to hack and rework Move MIPS reloc patch from pending to hack and rework it to adapt to new kernel 6.12 version. This required an additional patch. While at it also improve the text with the original info without cut. Link: https://github.com/openwrt/openwrt/pull/16547 Signed-off-by: Christian Marangi --- ...-declare-custom-module-alloc-free-fu.patch | 99 +++++++++++++++++++ ...g-calls-with-mno-long-calls-if-poss.patch} | 79 +++++++++------ 2 files changed, 149 insertions(+), 29 deletions(-) create mode 100644 target/linux/generic/hack-6.12/301-01-module-permit-to-declare-custom-module-alloc-free-fu.patch rename target/linux/generic/{pending-6.12/305-mips_module_reloc.patch => hack-6.12/301-02-mips-replace-mlong-calls-with-mno-long-calls-if-poss.patch} (83%) diff --git a/target/linux/generic/hack-6.12/301-01-module-permit-to-declare-custom-module-alloc-free-fu.patch b/target/linux/generic/hack-6.12/301-01-module-permit-to-declare-custom-module-alloc-free-fu.patch new file mode 100644 index 00000000000..611c203cbd8 --- /dev/null +++ b/target/linux/generic/hack-6.12/301-01-module-permit-to-declare-custom-module-alloc-free-fu.patch @@ -0,0 +1,99 @@ +From fec97dbb51697148ba881611f2b780a8d8a15885 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 14 Apr 2025 18:04:25 +0200 +Subject: [PATCH 1/2] module: permit to declare custom module alloc/free + function + +Permit to declare custom module alloc/free function that bypass the +execmem API. This works by making the alloc/free function weak +permitting an arch to declare a replacement for them. + +Signed-off-by: Christian Marangi +--- + include/linux/moduleloader.h | 5 +++++ + kernel/module/main.c | 33 ++++++++++++++++++++++++--------- + 2 files changed, 33 insertions(+), 9 deletions(-) + +--- a/include/linux/moduleloader.h ++++ b/include/linux/moduleloader.h +@@ -122,4 +122,9 @@ void module_arch_cleanup(struct module * + /* Any cleanup before freeing mod->module_init */ + void module_arch_freeing_init(struct module *mod); + ++void *module_arch_mem_alloc(struct module_memory *mem, ++ enum mod_mem_type type); ++ ++void module_arch_mem_free(struct module_memory *mem); ++ + #endif +--- a/kernel/module/main.c ++++ b/kernel/module/main.c +@@ -1191,22 +1191,20 @@ void __weak module_arch_freeing_init(str + { + } + +-static int module_memory_alloc(struct module *mod, enum mod_mem_type type) ++void *__weak module_arch_mem_alloc(struct module_memory *mem, ++ enum mod_mem_type type) + { +- unsigned int size = PAGE_ALIGN(mod->mem[type].size); + enum execmem_type execmem_type; + void *ptr; + +- mod->mem[type].size = size; +- + if (mod_mem_type_is_data(type)) + execmem_type = EXECMEM_MODULE_DATA; + else + execmem_type = EXECMEM_MODULE_TEXT; + +- ptr = execmem_alloc(execmem_type, size); ++ ptr = execmem_alloc(execmem_type, mem->size); + if (!ptr) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + + /* + * The pointer to these blocks of memory are stored on the module +@@ -1221,21 +1219,38 @@ static int module_memory_alloc(struct mo + */ + kmemleak_not_leak(ptr); + ++ return ptr; ++} ++ ++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; ++ ++ ptr = module_arch_mem_alloc(&mod->mem[type], type); ++ if (IS_ERR(ptr)) ++ return PTR_ERR(ptr); ++ + memset(ptr, 0, size); + mod->mem[type].base = ptr; + + return 0; + } + ++void __weak module_arch_mem_free(struct module_memory *mem) ++{ ++ execmem_free(mem->base); ++} ++ + 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; + +- execmem_free(ptr); ++ module_arch_mem_free(&mod->mem[type]); + } + + static void free_mod_mem(struct module *mod, bool unload_codetags) diff --git a/target/linux/generic/pending-6.12/305-mips_module_reloc.patch b/target/linux/generic/hack-6.12/301-02-mips-replace-mlong-calls-with-mno-long-calls-if-poss.patch similarity index 83% rename from target/linux/generic/pending-6.12/305-mips_module_reloc.patch rename to target/linux/generic/hack-6.12/301-02-mips-replace-mlong-calls-with-mno-long-calls-if-poss.patch index 6d13574b667..58a03148246 100644 --- a/target/linux/generic/pending-6.12/305-mips_module_reloc.patch +++ b/target/linux/generic/hack-6.12/301-02-mips-replace-mlong-calls-with-mno-long-calls-if-poss.patch @@ -1,13 +1,32 @@ +From 92ecd205bc5ab96b08295bf344c794da063a6f04 Mon Sep 17 00:00:00 2001 From: Felix Fietkau -Subject: mips: replace -mlong-calls with -mno-long-calls to make function calls faster in kernel modules to achieve this, try to +Date: Mon, 14 Apr 2025 18:05:45 +0200 +Subject: [PATCH 2/2] mips: replace -mlong-calls with -mno-long-calls if + possible + +This is a really old patch ported from MikroTik. It needs a an +additional patch to actually be implemented and both this and the old +one are considered HACK as they bypass normal kernel linux to make it +work. + +The original message quote: + +replace -mlong-calls with -mno-long-calls to make function +calls faster in kernel modules to achieve this, try to load +kernel modules to KSEG0 and if that doesn't work, use vmalloc +and fix up relocations with a jump table based on code from a +kernel patch by MikroTik. + +SVN-Revision: 16772 lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c Signed-off-by: Felix Fietkau +Signed-off-by: Christian Marangi --- - arch/mips/Makefile | 5 + + arch/mips/Makefile | 10 ++ arch/mips/include/asm/module.h | 5 + - arch/mips/kernel/module.c | 279 ++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 284 insertions(+), 5 deletions(-) + arch/mips/kernel/module.c | 282 ++++++++++++++++++++++++++++++++- + 3 files changed, 293 insertions(+), 4 deletions(-) --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -46,11 +65,18 @@ Signed-off-by: Felix Fietkau typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c -@@ -32,23 +32,261 @@ struct mips_hi16 { +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + + struct mips_hi16 { +@@ -30,14 +31,256 @@ struct mips_hi16 { static LIST_HEAD(dbe_list); static DEFINE_SPINLOCK(dbe_lock); --#ifdef MODULE_START +/* + * Get the potential max trampolines size required of the init and + * non-init sections. Only used if we cannot find enough contiguous @@ -125,7 +151,7 @@ Signed-off-by: Felix Fietkau + return ret; +} + -+#ifndef MODULE_START ++#ifndef MODULES_VADDR +static void *alloc_phys(unsigned long size) +{ + unsigned order; @@ -166,30 +192,23 @@ Signed-off-by: Felix Fietkau + } while (free); +} + -+ - void *module_alloc(unsigned long size) - { -+#ifdef MODULE_START - return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, - GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, - __builtin_return_address(0)); -+#else ++#ifndef MODULES_VADDR ++void *module_arch_mem_alloc(struct module_memory *mem, ++ enum mod_mem_type type) ++{ + void *ptr; + -+ if (size == 0) -+ return NULL; -+ -+ ptr = alloc_phys(size); ++ ptr = alloc_phys(mem->size); + + /* If we failed to allocate physically contiguous memory, + * fall back to regular vmalloc. The module loader code will + * create jump tables to handle long jumps */ + if (!ptr) -+ return vmalloc(size); ++ return vmalloc(mem->size); + + return ptr; ++} +#endif - } + +static inline bool is_phys_addr(void *ptr) +{ @@ -197,17 +216,19 @@ Signed-off-by: Felix Fietkau + return (KSEGX((unsigned long)ptr) == CKSEG0); +#else + return (KSEGX(ptr) == KSEG0); - #endif ++ #endif +} + ++#ifndef MODULES_VADDR +/* Free memory returned from module_alloc */ -+void module_memfree(void *module_region) ++void module_arch_mem_free(struct module_memory *mem) +{ -+ if (is_phys_addr(module_region)) -+ free_phys(module_region); ++ if (is_phys_addr(mem->base)) ++ free_phys(mem->base); + else -+ vfree(module_region); ++ vfree(mem->base); +} ++#endif + +static void *__module_alloc(int size, bool phys) +{ @@ -266,7 +287,7 @@ Signed-off-by: Felix Fietkau + + return 0; +} - ++ static void apply_r_mips_32(u32 *location, u32 base, Elf_Addr v) { *location = base + v; @@ -309,7 +330,7 @@ Signed-off-by: Felix Fietkau if (v % 4) { pr_err("module %s: dangerous R_MIPS_26 relocation\n", me->name); -@@ -56,13 +294,17 @@ static int apply_r_mips_26(struct module +@@ -45,13 +288,17 @@ static int apply_r_mips_26(struct module } if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { @@ -331,7 +352,7 @@ Signed-off-by: Felix Fietkau return 0; } -@@ -442,9 +684,36 @@ int module_finalize(const Elf_Ehdr *hdr, +@@ -431,9 +678,36 @@ int module_finalize(const Elf_Ehdr *hdr, list_add(&me->arch.dbe_list, &dbe_list); spin_unlock_irq(&dbe_lock); }