From: "Mike Rapoport (IBM)" <r...@kernel.org>

The memory allocations for kprobes on arm64 can be placed anywhere in
vmalloc address space and currently this is implemented with an override
of alloc_insn_page() in arm64.

Extend execmem_params with a range for generated code allocations and
make kprobes on arm64 use this extension rather than override
alloc_insn_page().

Signed-off-by: Mike Rapoport (IBM) <r...@kernel.org>
---
 arch/arm64/kernel/module.c         |  9 +++++++++
 arch/arm64/kernel/probes/kprobes.c |  7 -------
 include/linux/execmem.h            | 11 +++++++++++
 mm/execmem.c                       | 14 +++++++++++++-
 4 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index c3d999f3a3dd..52b09626bc0f 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -30,6 +30,13 @@ static struct execmem_params execmem_params = {
                        .alignment = MODULE_ALIGN,
                },
        },
+       .jit = {
+               .text = {
+                       .start = VMALLOC_START,
+                       .end = VMALLOC_END,
+                       .alignment = 1,
+               },
+       },
 };
 
 struct execmem_params __init *execmem_arch_params(void)
@@ -40,6 +47,8 @@ struct execmem_params __init *execmem_arch_params(void)
        execmem_params.modules.text.start = module_alloc_base;
        execmem_params.modules.text.end = module_alloc_end;
 
+       execmem_params.jit.text.pgprot = PAGE_KERNEL_ROX;
+
        /*
         * KASAN without KASAN_VMALLOC can only deal with module
         * allocations being served from the reserved module region,
diff --git a/arch/arm64/kernel/probes/kprobes.c 
b/arch/arm64/kernel/probes/kprobes.c
index 70b91a8c6bb3..6fccedd02b2a 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -129,13 +129,6 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
        return 0;
 }
 
-void *alloc_insn_page(void)
-{
-       return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
-                       GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
-                       NUMA_NO_NODE, __builtin_return_address(0));
-}
-
 /* arm kprobe: install breakpoint in text */
 void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
diff --git a/include/linux/execmem.h b/include/linux/execmem.h
index 2e1221310d13..dc7c9a446111 100644
--- a/include/linux/execmem.h
+++ b/include/linux/execmem.h
@@ -52,12 +52,23 @@ struct execmem_modules_range {
        struct execmem_range data;
 };
 
+/**
+ * struct execmem_jit_range - architecure parameters for address space
+ *                           suitable for JIT code allocations
+ * @text:      address range for text allocations
+ */
+struct execmem_jit_range {
+       struct execmem_range text;
+};
+
 /**
  * struct execmem_params -     architecure parameters for code allocations
  * @modules:   parameters for modules address space
+ * @jit:       parameters for jit memory address space
  */
 struct execmem_params {
        struct execmem_modules_range    modules;
+       struct execmem_jit_range        jit;
 };
 
 /**
diff --git a/mm/execmem.c b/mm/execmem.c
index f7bf496ad4c3..9730ecef9a30 100644
--- a/mm/execmem.c
+++ b/mm/execmem.c
@@ -89,7 +89,12 @@ void execmem_free(void *ptr)
 
 void *jit_text_alloc(size_t size)
 {
-       return execmem_text_alloc(size);
+       unsigned long start = execmem_params.jit.text.start;
+       unsigned long end = execmem_params.jit.text.end;
+       pgprot_t pgprot = execmem_params.jit.text.pgprot;
+       unsigned int align = execmem_params.jit.text.alignment;
+
+       return execmem_alloc(size, start, end, align, pgprot, 0, 0, false);
 }
 
 void jit_free(void *ptr)
@@ -135,6 +140,13 @@ static void execmem_init_missing(struct execmem_params *p)
                execmem_params.modules.data.fallback_start = 
m->text.fallback_start;
                execmem_params.modules.data.fallback_end = m->text.fallback_end;
        }
+
+       if (!execmem_params.jit.text.start) {
+               execmem_params.jit.text.start = m->text.start;
+               execmem_params.jit.text.end = m->text.end;
+               execmem_params.jit.text.alignment = m->text.alignment;
+               execmem_params.jit.text.pgprot = m->text.pgprot;
+       }
 }
 
 void __init execmem_init(void)
-- 
2.35.1

Reply via email to