arch/x86/boot/compressed/pgtable_64.c | 11 +++++++---- drivers/firmware/efi/libstub/x86-5lvl.c | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-)
This series addresses critical bugs in the kexec path when transitioning
from a kernel using 5-level page tables to one using 4-level page tables.
The root cause is improper handling of PGD entry value during the page level
transition. Specifically PGD entry value is masked with PAGE_MASK instead of
PTE_PFN_MASK, failing to account for high-order software bits like
_PAGE_BIT_NOPTISHADOW (bit 58).
When bit 58 (_PAGE_BIT_NOPTISHADOW) is set in the source kernel, the target
4-level kernel doesn't recognize it and fails to mask it properly, leading
to kexec failure.
Patch 1: Fixes the x86 boot compressed code path by replacing direct CR3
dereferencing with read_cr3_pa() and using PTE_PFN_MASK instead
of PAGE_MASK.
Patch 2: Applies the same fix to the EFI stub code path. (Done in a
separate patch as Fixes tag is different).
Co-developed-by: Kiryl Shutsemau <kas@kernel.org>
Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
Signed-off-by: Usama Arif <usamaarif642@gmail.com>
Reported-by: Michael van der Westhuizen <rmikey@meta.com>
Reported-by: Tobias Fleig <tfleig@meta.com>
The patches are based on aaa9c3550b60d6259d6ea8b1175ade8d1242444e (next-20251022)
v2 -> v3:
- Use native_pgd_val instead of pgd_val to fix broken build with allmodconfig.
I wanted to keep the code between pgtable_64.c and x86-5lvl.c consistent
so changed it in both patches
(Borislav Petkov and Ard Biesheuvel)
- Commit message improvements (Dave Hansen)
v1 -> v2:
- Remove patch 3 to fix kexec for source kernel in 5-level to 4-level
transition where the 4 level kernel doesnt have patch 1 and 2 (Dave Hansen)
- Add include for asm/pgtable.h to fix build for x86_64-allnoconfig (kernel test bot)
- Use native_read_cr3_pa and for both paths (Ard Biesheuvel)
Usama Arif (2):
x86/boot: Fix page table access in 5-level to 4-level paging
transition
efi/libstub: Fix page table access in 5-level to 4-level paging
transition
arch/x86/boot/compressed/pgtable_64.c | 11 +++++++----
drivers/firmware/efi/libstub/x86-5lvl.c | 4 ++--
2 files changed, 9 insertions(+), 6 deletions(-)
--
2.47.3
On Mon, Nov 03, 2025 at 02:09:21PM +0000, Usama Arif wrote:
> v2 -> v3:
> - Use native_pgd_val instead of pgd_val to fix broken build with allmodconfig.
> I wanted to keep the code between pgtable_64.c and x86-5lvl.c consistent
> so changed it in both patches
> (Borislav Petkov and Ard Biesheuvel)
> - Commit message improvements (Dave Hansen)
Did you run the build tests I suggested?
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On 03/11/2025 17:45, Borislav Petkov wrote: > On Mon, Nov 03, 2025 at 02:09:21PM +0000, Usama Arif wrote: >> v2 -> v3: >> - Use native_pgd_val instead of pgd_val to fix broken build with allmodconfig. >> I wanted to keep the code between pgtable_64.c and x86-5lvl.c consistent >> so changed it in both patches >> (Borislav Petkov and Ard Biesheuvel) >> - Commit message improvements (Dave Hansen) > > Did you run the build tests I suggested? > Yes, I did the below build tests: make LLVM=1 allnoconfig; make LLVM=1 bzImage make LLVM=1 defconfig; make LLVM=1 bzImage make LLVM=1 allmodconfig; make LLVM=1 bzImage make LLVM=1 allyesconfig; make LLVM=1 bzImage make LLVM=1 ARCH=i386 allnoconfig; make LLVM=1 ARCH=i386 bzImage make LLVM=1 ARCH=i386 defconfig; make LLVM=1 ARCH=i386 bzImage make LLVM=1 ARCH=i386 allmodconfig; make LLVM=1 ARCH=i386 bzImage make LLVM=1 ARCH=i386 allyesconfig; make LLVM=1 ARCH=i386 bzImage The i386 ones had a failure in lib/math/test_mul_u64_u64_div_u64.c:156:9 for linux-next/master so I rebased my patches on v6.17 and tested and they all built successfully.
On Mon, Nov 03, 2025 at 09:36:41PM +0300, Usama Arif wrote:
> Yes, I did the below build tests:
Thanks!
> make LLVM=1 allnoconfig; make LLVM=1 bzImage
> make LLVM=1 defconfig; make LLVM=1 bzImage
> make LLVM=1 allmodconfig; make LLVM=1 bzImage
> make LLVM=1 allyesconfig; make LLVM=1 bzImage
>
> make LLVM=1 ARCH=i386 allnoconfig; make LLVM=1 ARCH=i386 bzImage
> make LLVM=1 ARCH=i386 defconfig; make LLVM=1 ARCH=i386 bzImage
> make LLVM=1 ARCH=i386 allmodconfig; make LLVM=1 ARCH=i386 bzImage
> make LLVM=1 ARCH=i386 allyesconfig; make LLVM=1 ARCH=i386 bzImage
Next time try gcc too pls. :-) That's the first compiler we ever supported.
> The i386 ones had a failure in lib/math/test_mul_u64_u64_div_u64.c:156:9 for
> linux-next/master so I rebased my patches on v6.17 and tested and they all
> built successfully.
Yeah, that was pointless.
You can simply say that the 32-bit build fails because of an unrelated reason.
But backporting it to another kernel doesn't have any bearing on the code this
is going to be applied ontop of so...
But not a problem, I'll do the rest of the testing here.
Thanks again.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
© 2016 - 2026 Red Hat, Inc.