summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel/module.c
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2016-09-26 12:54:41 -0700
committerDmitry Shmidt <dimitrysh@google.com>2016-09-26 14:58:53 -0700
commit8760f8e3d9806a940d759c9e12fff7eb7130b9ab (patch)
tree3471f2a1dd633efdda95765f905ff2f3d4455175 /arch/arm64/kernel/module.c
parent734bcf32c23442e81891641ae05e08108a4010d5 (diff)
parent4055d6b56ac1de5b900ce6f0b484996aa357ee66 (diff)
Merge remote-tracking branch 'common/android-4.4' into android-4.4.y
Change-Id: I6c4e7f9f47392d4b334f71e2b20f2ccf33827632
Diffstat (limited to 'arch/arm64/kernel/module.c')
-rw-r--r--arch/arm64/kernel/module.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 93e970231ca9..7f316982ce00 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -34,10 +34,26 @@ void *module_alloc(unsigned long size)
{
void *p;
- p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END,
+ p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
+ module_alloc_base + MODULES_VSIZE,
GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
NUMA_NO_NODE, __builtin_return_address(0));
+ if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
+ !IS_ENABLED(CONFIG_KASAN))
+ /*
+ * KASAN can only deal with module allocations being served
+ * from the reserved module region, since the remainder of
+ * the vmalloc region is already backed by zero shadow pages,
+ * and punching holes into it is non-trivial. Since the module
+ * region is not randomized when KASAN is enabled, it is even
+ * less likely that the module region gets exhausted, so we
+ * can simply omit this fallback in that case.
+ */
+ p = __vmalloc_node_range(size, MODULE_ALIGN, VMALLOC_START,
+ VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
+ NUMA_NO_NODE, __builtin_return_address(0));
+
if (p && (kasan_module_alloc(p, size) < 0)) {
vfree(p);
return NULL;
@@ -361,6 +377,13 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
case R_AARCH64_CALL26:
ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 26,
AARCH64_INSN_IMM_26);
+
+ if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
+ ovf == -ERANGE) {
+ val = module_emit_plt_entry(me, &rel[i], sym);
+ ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2,
+ 26, AARCH64_INSN_IMM_26);
+ }
break;
default: