Commit 16459fe7 authored by Andrew Cooper's avatar Andrew Cooper Committed by Andrew Morton
Browse files

x86/kfence: fix booting on 32bit non-PAE systems

The original patch inverted the PTE unconditionally to avoid
L1TF-vulnerable PTEs, but Linux doesn't make this adjustment in 2-level
paging.

Adjust the logic to use the flip_protnone_guard() helper, which is a nop
on 2-level paging but inverts the address bits in all other paging modes.

This doesn't matter for the Xen aspect of the original change.  Linux no
longer supports running 32bit PV under Xen, and Xen doesn't support
running any 32bit PV guests without using PAE paging.

Link: https://lkml.kernel.org/r/20260126211046.2096622-1-andrew.cooper3@citrix.com


Fixes: b505f194 ("x86/kfence: avoid writing L1TF-vulnerable PTEs")
Reported-by: default avatarRyusuke Konishi <konishi.ryusuke@gmail.com>
Closes: https://lore.kernel.org/lkml/CAKFNMokwjw68ubYQM9WkzOuH51wLznHpEOMSqtMoV1Rn9JV_gw@mail.gmail.com/


Signed-off-by: default avatarAndrew Cooper <andrew.cooper3@citrix.com>
Tested-by: default avatarRyusuke Konishi <konishi.ryusuke@gmail.com>
Tested-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Cc: Alexander Potapenko <glider@google.com>
Cc: Marco Elver <elver@google.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Jann Horn <jannh@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent bd587829
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
	unsigned int level;
	pte_t *pte = lookup_address(addr, &level);
	pteval_t val;
	pteval_t val, new;

	if (WARN_ON(!pte || level != PG_LEVEL_4K))
		return false;
@@ -57,11 +57,12 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect)
		return true;

	/*
	 * Otherwise, invert the entire PTE.  This avoids writing out an
	 * Otherwise, flip the Present bit, taking care to avoid writing an
	 * L1TF-vulnerable PTE (not present, without the high address bits
	 * set).
	 */
	set_pte(pte, __pte(~val));
	new = val ^ _PAGE_PRESENT;
	set_pte(pte, __pte(flip_protnone_guard(val, new, PTE_PFN_MASK)));

	/*
	 * If the page was protected (non-present) and we're making it