From d4d9961d4156c6d833a73ec60d644fb0b5e1525a Mon Sep 17 00:00:00 2001 From: vasilito Date: Mon, 6 Jul 2026 02:24:44 +0300 Subject: [PATCH] x86_64: map FACS physical address before parsing in acpi::init The FACS address from FADT x_firmware_ctrl is a physical address. Dereferencing it directly caused a page fault after the FADT offset fix yielded a valid (but unmapped) physical address. Use get_sdt() to map it into kernel space before passing it to facs::init. Author: vasilito --- src/acpi/mod.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/acpi/mod.rs b/src/acpi/mod.rs index f82ab9a078..0c79eb06ad 100644 --- a/src/acpi/mod.rs +++ b/src/acpi/mod.rs @@ -190,23 +190,26 @@ pub unsafe fn init(already_supplied_rsdp: Option>) { let facs_addr = fadt::x_firmware_ctrl(); info!("FACS x_firmware_ctrl = {:#x}", facs_addr); if facs_addr != 0 { - // SAFETY: The FACS address is a physical - // address stored in the FADT. The boot-time page - // table maps the FACS into the kernel's address - // space (firmware tables are below 4GB on x86_64). - let facs_sdt = unsafe { &*(facs_addr as *const Sdt) }; + // The FACS address from the FADT is a physical + // address. Map it into kernel space before parsing. + let facs_sdt = get_sdt( + PhysicalAddress::new(facs_addr as usize), + &mut KernelMapper::lock_rw(), + ); facs::init(facs_sdt); } else { let facs_addr = fadt::firmware_ctrl() as u64; if facs_addr != 0 { - // SAFETY: same as above. - let facs_sdt = - unsafe { &*(facs_addr as *const Sdt) }; + let facs_sdt = get_sdt( + PhysicalAddress::new(facs_addr as usize), + &mut KernelMapper::lock_rw(), + ); facs::init(facs_sdt); } else { warn!("ACPI: no FACS found (neither x_firmware_ctrl nor firmware_ctrl), S3 resume path disabled"); } } + info!("GSBASE after facs::init: {:#x}", x86::msr::rdmsr(x86::msr::IA32_GS_BASE)); } else { error!("NO RSDP FOUND"); }