From: Dave Hansen Frédéric reported: x86/mm: Checked W+X mappings: FAILED, 7 W+X pages found. errors on a build with modules disabled. There are some build dependencies in play: * ARCH_HAS_EXECMEM_ROX depends on STRICT_MODULE_RWX * STRICT_MODULE_RWX depends on MODULES * execmem_restore_rox() is a stub without ARCH_HAS_EXECMEM_ROX=y execmem_restore_rox() is what the x86 "ITS" code uses to zap its W+X mappings during early boot. The error message comes from CONFIG_DEBUG_WX which is independent from any of the other options. But the nutty part is that there is any connection at all between ARCH_HAS_EXECMEM_ROX and STRICT_MODULE_RWX. Restore a functional execmem_restore_rox() to all 64-bit builds by eliminating the STRICT_MODULE_RWX dependency. Then, turn our attention to execmem. 47410d839fcd "x86/Kconfig: only enable ROX cache...") was trying to make module memory access more permissive unless STRICT_MODULE_RWX is in play. For execmem, never consider module memory to be ROX except under STRICT_MODULE_RWX. This seems to fix Frédéric's issue, but I'm a bit worried that it has other implications in the execmem code. For instance, the module_enable_text_rox() loop is now rather weird mem->is_rox is now directly dependent on STRICT_MODULE_RWX. Mike, do you see anything bad happening on the execmem side if we do this? Signed-off-by: Dave Hansen Tested-by: Frederic MARIE-JOSEPH Reported-by: Frederic MARIE-JOSEPH Link: https://lore.kernel.org/all/20261001-x86-fault-spurious-rw-v1-1-7fe1189b5efd@imperva.com/ Fixes: a82b26451de1 ("x86/its: explicitly manage permissions for ITS pages") Cc: Mike Rapoport (Microsoft) Cc: Peter Zijlstra (Intel) Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x86@kernel.org Cc: "H. Peter Anvin" Cc: Luis Chamberlain Cc: Petr Pavlu Cc: Daniel Gomez Cc: Sami Tolvanen Cc: Aaron Tomlin Cc: linux-kernel@vger.kernel.org Cc: linux-modules@vger.kernel.org --- b/arch/x86/Kconfig | 2 +- b/kernel/module/main.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff -puN arch/x86/Kconfig~x86-STRICT_MODULE_RWX arch/x86/Kconfig --- a/arch/x86/Kconfig~x86-STRICT_MODULE_RWX 2026-10-01 07:11:50.443595828 -0700 +++ b/arch/x86/Kconfig 2026-10-01 07:11:50.454595751 -0700 @@ -85,7 +85,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 && STRICT_MODULE_RWX + 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 -puN kernel/module/main.c~x86-STRICT_MODULE_RWX kernel/module/main.c --- a/kernel/module/main.c~x86-STRICT_MODULE_RWX 2026-10-01 07:11:50.449595786 -0700 +++ b/kernel/module/main.c 2026-10-01 09:47:20.842360625 -0700 @@ -1355,7 +1355,8 @@ static int module_memory_alloc(struct mo if (!ptr) return -ENOMEM; - mod->mem[type].is_rox = execmem_is_rox(execmem_type); + if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + mod->mem[type].is_rox = execmem_is_rox(execmem_type); /* * The pointer to these blocks of memory are stored on the module _