kernel: fix crashes on MIPS when loading kernel modules under memory pressure
authorFelix Fietkau <nbd@nbd.name>
Wed, 15 Feb 2017 11:33:03 +0000 (12:33 +0100)
committerFelix Fietkau <nbd@nbd.name>
Wed, 15 Feb 2017 11:35:17 +0000 (12:35 +0100)
When memory is tight, modules may need to be loaded into vmalloc()
space. The code then has to generate jump trampolines which enable
relocations between vmalloc space and physical address space.

The code had a bug that was freeing these trampolines even when the
module was successfully loaded.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
target/linux/generic/patches-3.18/305-mips_module_reloc.patch
target/linux/generic/patches-4.4/305-mips_module_reloc.patch
target/linux/generic/patches-4.9/305-mips_module_reloc.patch

index f8ca91401a7a6f207255a24606095eebddf3152a..fae7e70f0e54ea37b458419674b271a9bacf081a 100644 (file)
  
        return 0;
  }
-@@ -287,9 +529,33 @@ int module_finalize(const Elf_Ehdr *hdr,
+@@ -287,9 +529,36 @@ int module_finalize(const Elf_Ehdr *hdr,
                list_add(&me->arch.dbe_list, &dbe_list);
                spin_unlock_irq(&dbe_lock);
        }
  
 +void module_arch_freeing_init(struct module *mod)
 +{
++      if (mod->state == MODULE_STATE_LIVE)
++              return;
++
 +      if (mod->arch.phys_plt_tbl) {
 +              __module_free(mod->arch.phys_plt_tbl);
 +              mod->arch.phys_plt_tbl = NULL;
index 8b3975fe09516dcb32734bf041815c04324b11d9..944921fff7a0d0d33515cb84a2cb81e9cca42d0e 100644 (file)
  
        return 0;
  }
-@@ -287,9 +528,33 @@ int module_finalize(const Elf_Ehdr *hdr,
+@@ -287,9 +528,36 @@ int module_finalize(const Elf_Ehdr *hdr,
                list_add(&me->arch.dbe_list, &dbe_list);
                spin_unlock_irq(&dbe_lock);
        }
  
 +void module_arch_freeing_init(struct module *mod)
 +{
++      if (mod->state == MODULE_STATE_LIVE)
++              return;
++
 +      if (mod->arch.phys_plt_tbl) {
 +              __module_free(mod->arch.phys_plt_tbl);
 +              mod->arch.phys_plt_tbl = NULL;
index 997105ba1aa386b2b44239fa25623430ceee8457..1c2bd0aa9f23cfb5cfb5f4664cc151ef52f2888f 100644 (file)
  
        return 0;
  }
-@@ -349,9 +591,33 @@ int module_finalize(const Elf_Ehdr *hdr,
+@@ -349,9 +591,36 @@ int module_finalize(const Elf_Ehdr *hdr,
                list_add(&me->arch.dbe_list, &dbe_list);
                spin_unlock_irq(&dbe_lock);
        }
  
 +void module_arch_freeing_init(struct module *mod)
 +{
++      if (mod->state == MODULE_STATE_LIVE)
++              return;
++
 +      if (mod->arch.phys_plt_tbl) {
 +              __module_free(mod->arch.phys_plt_tbl);
 +              mod->arch.phys_plt_tbl = NULL;