]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
generic: 6.12: move MIPS reloc patch from pending to hack and rework
authorChristian Marangi <ansuelsmth@gmail.com>
Mon, 14 Apr 2025 16:34:10 +0000 (18:34 +0200)
committerChristian Marangi <ansuelsmth@gmail.com>
Wed, 30 Apr 2025 14:26:32 +0000 (16:26 +0200)
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 <ansuelsmth@gmail.com>
target/linux/generic/hack-6.12/301-01-module-permit-to-declare-custom-module-alloc-free-fu.patch [new file with mode: 0644]
target/linux/generic/hack-6.12/301-02-mips-replace-mlong-calls-with-mno-long-calls-if-poss.patch [moved from target/linux/generic/pending-6.12/305-mips_module_reloc.patch with 83% similarity]

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 (file)
index 0000000..611c203
--- /dev/null
@@ -0,0 +1,99 @@
+From fec97dbb51697148ba881611f2b780a8d8a15885 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+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 <ansuelsmth@gmail.com>
+---
+ 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)
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 6d13574b667bff05f6eb0c5a38d07b32ea6ddd51..58a03148246c0f0da34d673e403d76d39b2beed3 100644 (file)
@@ -1,13 +1,32 @@
+From 92ecd205bc5ab96b08295bf344c794da063a6f04 Mon Sep 17 00:00:00 2001
 From: Felix Fietkau <nbd@nbd.name>
-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 <nbd@nbd.name>
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 ---
- 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 <nbd@nbd.name>
  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 <linux/kernel.h>
+ #include <linux/spinlock.h>
+ #include <linux/jump_label.h>
++#include <linux/vmalloc.h>
+ #include <asm/jump_label.h>
+ 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 <nbd@nbd.name>
 +      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 <nbd@nbd.name>
 +      } 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 <nbd@nbd.name>
 +      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 <nbd@nbd.name>
 +
 +      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 <nbd@nbd.name>
        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 <nbd@nbd.name>
  
        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);
        }