| From: "Mike Rapoport (Microsoft)" <rppt@kernel.org> |
| Subject: x86/module: enable ROX caches for module text on 64 bit |
| Date: Wed, 23 Oct 2024 19:27:11 +0300 |
| |
| Enable execmem's cache of PMD_SIZE'ed pages mapped as ROX for module text |
| allocations on 64 bit. |
| |
| Link: https://lkml.kernel.org/r/20241023162711.2579610-9-rppt@kernel.org |
| Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> |
| Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> |
| Tested-by: kdevops <kdevops@lists.linux.dev> |
| Cc: Andreas Larsson <andreas@gaisler.com> |
| Cc: Andy Lutomirski <luto@kernel.org> |
| Cc: Ard Biesheuvel <ardb@kernel.org> |
| Cc: Arnd Bergmann <arnd@arndb.de> |
| Cc: Borislav Petkov (AMD) <bp@alien8.de> |
| Cc: Brian Cain <bcain@quicinc.com> |
| Cc: Catalin Marinas <catalin.marinas@arm.com> |
| Cc: Christophe Leroy <christophe.leroy@csgroup.eu> |
| Cc: Christoph Hellwig <hch@lst.de> |
| Cc: Dave Hansen <dave.hansen@linux.intel.com> |
| Cc: Dinh Nguyen <dinguyen@kernel.org> |
| Cc: Geert Uytterhoeven <geert@linux-m68k.org> |
| Cc: Guo Ren <guoren@kernel.org> |
| Cc: Helge Deller <deller@gmx.de> |
| Cc: Huacai Chen <chenhuacai@kernel.org> |
| Cc: Ingo Molnar <mingo@redhat.com> |
| Cc: Johannes Berg <johannes@sipsolutions.net> |
| Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> |
| Cc: Kent Overstreet <kent.overstreet@linux.dev> |
| Cc: Liam R. Howlett <Liam.Howlett@Oracle.com> |
| Cc: Mark Rutland <mark.rutland@arm.com> |
| Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org> |
| Cc: Matt Turner <mattst88@gmail.com> |
| Cc: Max Filippov <jcmvbkbc@gmail.com> |
| Cc: Michael Ellerman <mpe@ellerman.id.au> |
| Cc: Michal Simek <monstr@monstr.eu> |
| Cc: Oleg Nesterov <oleg@redhat.com> |
| Cc: Palmer Dabbelt <palmer@dabbelt.com> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Richard Weinberger <richard@nod.at> |
| Cc: Russell King <linux@armlinux.org.uk> |
| Cc: Song Liu <song@kernel.org> |
| Cc: Stafford Horne <shorne@gmail.com> |
| Cc: Steven Rostedt (Google) <rostedt@goodmis.org> |
| Cc: Suren Baghdasaryan <surenb@google.com> |
| Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Uladzislau Rezki (Sony) <urezki@gmail.com> |
| Cc: Vineet Gupta <vgupta@kernel.org> |
| Cc: Will Deacon <will@kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| arch/x86/Kconfig | 1 + |
| arch/x86/mm/init.c | 37 ++++++++++++++++++++++++++++++++++++- |
| 2 files changed, 37 insertions(+), 1 deletion(-) |
| |
| --- a/arch/x86/Kconfig~x86-module-enable-rox-caches-for-module-text-on-64-bit |
| +++ a/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 |
| --- a/arch/x86/mm/init.c~x86-module-enable-rox-caches-for-module-text-on-64-bit |
| +++ a/arch/x86/mm/init.c |
| @@ -1053,18 +1053,53 @@ unsigned long arch_max_swapfile_size(voi |
| #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, |
| _ |