Merge tag 's390-6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux-block.git] / arch / s390 / kernel / module.c
index b9dbf0c483ed6bd8d41ef64c83c6345eacc602dd..f1b35dcdf3eb520cbdefad6d57c333f9598aceae 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/facility.h>
 #include <asm/ftrace.lds.h>
 #include <asm/set_memory.h>
+#include <asm/setup.h>
 
 #if 0
 #define DEBUGP printk
 
 #define PLT_ENTRY_SIZE 22
 
+static unsigned long get_module_load_offset(void)
+{
+       static DEFINE_MUTEX(module_kaslr_mutex);
+       static unsigned long module_load_offset;
+
+       if (!kaslr_enabled())
+               return 0;
+       /*
+        * Calculate the module_load_offset the first time this code
+        * is called. Once calculated it stays the same until reboot.
+        */
+       mutex_lock(&module_kaslr_mutex);
+       if (!module_load_offset)
+               module_load_offset = get_random_u32_inclusive(1, 1024) * PAGE_SIZE;
+       mutex_unlock(&module_kaslr_mutex);
+       return module_load_offset;
+}
+
 void *module_alloc(unsigned long size)
 {
        gfp_t gfp_mask = GFP_KERNEL;
@@ -42,9 +61,11 @@ void *module_alloc(unsigned long size)
 
        if (PAGE_ALIGN(size) > MODULES_LEN)
                return NULL;
-       p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END,
-                                gfp_mask, PAGE_KERNEL_EXEC, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
-                                __builtin_return_address(0));
+       p = __vmalloc_node_range(size, MODULE_ALIGN,
+                                MODULES_VADDR + get_module_load_offset(),
+                                MODULES_END, gfp_mask, PAGE_KERNEL,
+                                VM_FLUSH_RESET_PERMS | VM_DEFER_KMEMLEAK,
+                                NUMA_NO_NODE, __builtin_return_address(0));
        if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
                vfree(p);
                return NULL;
@@ -491,7 +512,7 @@ static int module_alloc_ftrace_hotpatch_trampolines(struct module *me,
        start = module_alloc(numpages * PAGE_SIZE);
        if (!start)
                return -ENOMEM;
-       set_memory_ro((unsigned long)start, numpages);
+       set_memory_rox((unsigned long)start, numpages);
        end = start + size;
 
        me->arch.trampolines_start = (struct ftrace_hotpatch_trampoline *)start;