public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86: fix oops caused by old EFI info on kexec boot
@ 2025-11-26 17:32 James Le Cuirot
  2025-12-03 18:12 ` Ingo Molnar
  0 siblings, 1 reply; 9+ messages in thread
From: James Le Cuirot @ 2025-11-26 17:32 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, H . Peter Anvin, Ard Biesheuvel, James Le Cuirot

kexec on x86 passes initrd details via the boot_params. If no initrd is
supplied, then ramdisk_size is 0. When determining whether to reserve
memory for the initrd on the subsequent boot, ramdisk_size being 0
causes the logic to fall back to phys_initrd_start and phys_initrd_size
set from the EFI tables in efi.c. This is stale information from the
initial boot. The system continues to boot and has even been seen to
function under heavy load for days, but allocating very large amounts of
memory reliably triggers an oops rather than the OOM killer.

  BUG: kernel NULL pointer dereference, address: 0000000000000008
  #PF: supervisor write access in kernel mode
  #PF: error_code(0x0002) - not-present page
  PGD 0 P4D 0
  Oops: Oops: 0002 [#1] SMP NOPTI

This issue was introduced in f4dc7fffa9873db50ec25624572f8217a6225de8
when the EFI stub initrd loading was unified between architectures.

Avoid the issue by checking whether the bootloader is not kexec before
falling back to the EFI table values.

I strongly suspect this also affects other architectures. A different
fix would be required there, and I do have a fix in mind, but I was
unable to reproduce the issue under QEMU's aarch64 virt machine. I think
this is at least partly because it relies on ACPI while kexec passes the
initd details via the device tree.

Signed-off-by: James Le Cuirot <chewi@gentoo.org>
---
 arch/x86/kernel/setup.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 1b2edd07a3e1..8aa65daf121f 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -300,7 +300,8 @@ static u64 __init get_ramdisk_image(void)
 
 	ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;
 
-	if (ramdisk_image == 0)
+	/* Don't fall back for kexec as phys_initrd_start will be stale */
+	if (ramdisk_image == 0 && (boot_params.hdr.type_of_loader >> 4) != 0xD)
 		ramdisk_image = phys_initrd_start;
 
 	return ramdisk_image;
@@ -311,7 +312,8 @@ static u64 __init get_ramdisk_size(void)
 
 	ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;
 
-	if (ramdisk_size == 0)
+	/* Don't fall back for kexec as phys_initrd_start will be stale */
+	if (ramdisk_size == 0 && (boot_params.hdr.type_of_loader >> 4) != 0xD)
 		ramdisk_size = phys_initrd_size;
 
 	return ramdisk_size;
-- 
2.51.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-12-06 11:45 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-26 17:32 [PATCH] x86: fix oops caused by old EFI info on kexec boot James Le Cuirot
2025-12-03 18:12 ` Ingo Molnar
2025-12-03 20:59   ` H. Peter Anvin
2025-12-03 21:27     ` H. Peter Anvin
2025-12-06 11:45       ` Ingo Molnar
2025-12-03 22:57   ` Ard Biesheuvel
2025-12-03 23:01     ` Ard Biesheuvel
2025-12-04 21:40       ` James Le Cuirot
2025-12-04 23:18         ` H. Peter Anvin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox