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

Enable execmem's cache of PMD_SIZE'ed pages mapped as ROX for module
text allocations on 64 bit.

Signed-off-by: Mike Rapoport (Microsoft) <r...@kernel.org>
Reviewed-by: Luis Chamberlain <mcg...@kernel.org>
Tested-by: kdevops <kdev...@lists.linux.dev>
---
 arch/x86/Kconfig   |  1 +
 arch/x86/mm/init.c | 37 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2852fcd82cbd..ff71d18253ba 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -83,6 +83,7 @@ config X86
        select ARCH_HAS_DMA_OPS                 if GART_IOMMU || XEN
        select ARCH_HAS_EARLY_DEBUG             if KGDB
        select ARCH_HAS_ELF_RANDOMIZE
+       select ARCH_HAS_EXECMEM_ROX             if X86_64
        select ARCH_HAS_FAST_MULTIPLIER
        select ARCH_HAS_FORTIFY_SOURCE
        select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index eb503f53c319..c2e4f389f47f 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -1053,18 +1053,53 @@ unsigned long arch_max_swapfile_size(void)
 #ifdef CONFIG_EXECMEM
 static struct execmem_info execmem_info __ro_after_init;
 
+#ifdef CONFIG_ARCH_HAS_EXECMEM_ROX
+void execmem_fill_trapping_insns(void *ptr, size_t size, bool writeable)
+{
+       /* fill memory with INT3 instructions */
+       if (writeable)
+               memset(ptr, INT3_INSN_OPCODE, size);
+       else
+               text_poke_set(ptr, INT3_INSN_OPCODE, size);
+}
+#endif
+
 struct execmem_info __init *execmem_arch_setup(void)
 {
        unsigned long start, offset = 0;
+       enum execmem_range_flags flags;
+       pgprot_t pgprot;
 
        if (kaslr_enabled())
                offset = get_random_u32_inclusive(1, 1024) * PAGE_SIZE;
 
        start = MODULES_VADDR + offset;
 
+       if (IS_ENABLED(CONFIG_ARCH_HAS_EXECMEM_ROX)) {
+               pgprot = PAGE_KERNEL_ROX;
+               flags = EXECMEM_KASAN_SHADOW | EXECMEM_ROX_CACHE;
+       } else {
+               pgprot = PAGE_KERNEL;
+               flags = EXECMEM_KASAN_SHADOW;
+       }
+
        execmem_info = (struct execmem_info){
                .ranges = {
-                       [EXECMEM_DEFAULT] = {
+                       [EXECMEM_MODULE_TEXT] = {
+                               .flags  = flags,
+                               .start  = start,
+                               .end    = MODULES_END,
+                               .pgprot = pgprot,
+                               .alignment = MODULE_ALIGN,
+                       },
+                       [EXECMEM_KPROBES ... EXECMEM_BPF] = {
+                               .flags  = EXECMEM_KASAN_SHADOW,
+                               .start  = start,
+                               .end    = MODULES_END,
+                               .pgprot = PAGE_KERNEL,
+                               .alignment = MODULE_ALIGN,
+                       },
+                       [EXECMEM_MODULE_DATA] = {
                                .flags  = EXECMEM_KASAN_SHADOW,
                                .start  = start,
                                .end    = MODULES_END,
-- 
2.43.0


Reply via email to