[RFC PATCH] x86/mm: Disable PTI for kernel_ident_mapping_init()

David Woodhouse dwmw2 at infradead.org
Mon Nov 25 09:05:07 PST 2024


From: David Woodhouse <dwmw at amazon.co.uk>

With PTI enabled, set_p4d() and set_pgd() will scribble over the end of
the 4KiB page allocated by the ->alloc_pgt_page() callback, expecting it
to have been an 8KiB allocation with the userspace version immediately
after the kernel's version.

So build *just* this code without PTI support. And without the PV MMU
ops too, since that would redirect to the standard build of those
functions which would have PTI enabled.

Signed-off-by: David Woodhouse <dwmw at amazon.co.uk>
---
Not sure I like this very much, but it works, and mirrors what
arch/x86/boot/compressed/ident_map_64.c already does.

We can't build the rest of the code in init_64.c with those config
options turned off, or Xen PV doesn't boot any more. So just build it
separately instead of #including it.

Now kexec is a little more reliable and doesn't scribble over adjacent
memory when building the page tables.

 arch/x86/mm/Makefile    |  1 +
 arch/x86/mm/ident_map.c | 15 +++++++++++++++
 arch/x86/mm/init_64.c   |  2 --
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 690fbf48e853..134302863233 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -37,6 +37,7 @@ CFLAGS_mem_encrypt_identity.o	:= -fno-stack-protector
 CFLAGS_fault.o := -I $(src)/../include/asm/trace
 
 obj-$(CONFIG_X86_32)		+= pgtable_32.o iomap_32.o
+obj-$(CONFIG_X86_64)		+= ident_map.o
 
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_PTDUMP_CORE)	+= dump_pagetables.o
diff --git a/arch/x86/mm/ident_map.c b/arch/x86/mm/ident_map.c
index 437e96fb4977..090240f98141 100644
--- a/arch/x86/mm/ident_map.c
+++ b/arch/x86/mm/ident_map.c
@@ -4,6 +4,21 @@
  * included by both the compressed kernel and the regular kernel.
  */
 
+/*
+ * If PTI is enabled, the standard set_p4d() et al functions will assume
+ * that each allocation is 8KiB, with the userspace page table 4KiB above
+ * the kernel one. Since users of the kernel_ident_mapping_init() code all
+ * allocate only a 4KiB page in their ->alloc_pgt_page() callback, this
+ * leads to scribbling over the end of the allocation. So *just* for this
+ * identmap code, disable PTI and disable the paravirt MMU ops which would
+ * redirect to the normally-compiled version that will use PTI.
+ */
+#undef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
+#undef CONFIG_PARAVIRT_XXL
+
+#include <linux/pgtable.h>
+#include <asm/init.h>
+
 static void free_pte(struct x86_mapping_info *info, pmd_t *pmd)
 {
 	pte_t *pte = pte_offset_kernel(pmd, 0);
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index ff253648706f..784f8d1c9140 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -58,8 +58,6 @@
 
 #include "mm_internal.h"
 
-#include "ident_map.c"
-
 #define DEFINE_POPULATE(fname, type1, type2, init)		\
 static inline void fname##_init(struct mm_struct *mm,		\
 		type1##_t *arg1, type2##_t *arg2, bool init)	\
-- 
2.43.0


-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5965 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/kexec/attachments/20241125/eaa9a41c/attachment.p7s>


More information about the kexec mailing list