]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/kfence: fix booting on 32bit non-PAE systems
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 26 Jan 2026 21:10:46 +0000 (21:10 +0000)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 3 Feb 2026 02:43:55 +0000 (18:43 -0800)
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: b505f1944535 ("x86/kfence: avoid writing L1TF-vulnerable PTEs")
Reported-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Closes: https://lore.kernel.org/lkml/CAKFNMokwjw68ubYQM9WkzOuH51wLznHpEOMSqtMoV1Rn9JV_gw@mail.gmail.com/
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Tested-by: Borislav 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: Andrew Morton <akpm@linux-foundation.org>
arch/x86/include/asm/kfence.h

index acf9ffa1a1718349dbe2356628dad86e8065e9e4..dfd5c74ba41a2f34499679dadfed2ca9595806c5 100644 (file)
@@ -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