From 977b06d432dfa5de589aacf66785b6044533549a Mon Sep 17 00:00:00 2001 From: Zhang Junyu Date: Fri, 19 Jun 2026 05:49:40 +0000 Subject: [PATCH 1/2] fix: Introduce HW_REDUCED to avoid pm1a --- crates/vm-device/src/device/dummy.rs | 5 ----- crates/vm-firmware/src/acpi/type/fadt.rs | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/crates/vm-device/src/device/dummy.rs b/crates/vm-device/src/device/dummy.rs index c6ba1c0..eebae81 100644 --- a/crates/vm-device/src/device/dummy.rs +++ b/crates/vm-device/src/device/dummy.rs @@ -9,8 +9,6 @@ pub struct Dummy; impl Dummy { pub fn new(pio_allocator: &mut RangeAllocator) -> Result { - let _ = pio_allocator.reserve(0x1004, 1)?; - let _ = pio_allocator.reserve(0x1006, 1)?; let _ = pio_allocator.reserve(0x87, 1)?; Ok(Dummy) @@ -34,9 +32,6 @@ impl Device for Dummy { impl PioDevice for Dummy { fn ports(&self) -> Vec> { vec![ - // acpi pm1a - 0x1004..0x1005, - 0x1006..0x1007, // TODO 0x87..0x88, ] diff --git a/crates/vm-firmware/src/acpi/type/fadt.rs b/crates/vm-firmware/src/acpi/type/fadt.rs index a1e1f41..4fa39fc 100644 --- a/crates/vm-firmware/src/acpi/type/fadt.rs +++ b/crates/vm-firmware/src/acpi/type/fadt.rs @@ -14,6 +14,16 @@ use crate::acpi::r#type::common_header::CommonHeader; use crate::acpi::r#type::generic_address_structure_format::GenericAddressStructureFormat; use crate::acpi::utils::checksum; +// A zero indicates the power button is handled as a fixed feature programming model; +// a one indicates the power button is handled as a control method device. +// If the system does not have a power button, this value would be “1” and no power button device would be present. +const ACPI_FADT_POWER_BUTTON: u32 = 1 << 4; /* 04: [V1] Power button is handled as a control method device */ +// A zero indicates the sleep button is handled as a fixed feature programming model; +// a one indicates the sleep button is handled as a control method device. +// If the system does not have a sleep button, this value would be “1” and no sleep button device would be present. +const ACPI_FADT_SLEEP_BUTTON: u32 = 1 << 5; /* 05: [V1] Sleep button is handled as a control method device */ +const FADT_F_HW_REDUCED_ACPI: u32 = 1 << 20; /* 20: [V5] ACPI hardware is not implemented (ACPI 5.0) */ + #[derive(Default, Immutable, IntoBytes)] #[repr(C, packed)] pub struct Fadt { @@ -89,20 +99,10 @@ impl Fadt { creator_id: CREATOR_ID, creator_revision: CREATOR_REVISION, }, - flags: 0, + flags: ACPI_FADT_POWER_BUTTON | ACPI_FADT_SLEEP_BUTTON | FADT_F_HW_REDUCED_ACPI, fadt_minor_version: 5, // ACPI 6.6 specification says it is 5. x_dsdt, hypervisor_vendor_id: HYPERVISOR_VENDOR_ID, - // TODO - pm1a_cnt_blk: 0x1000, - // TODO - pm1_evt_len: 16, - // TODO - pm1a_evt_blk: 0x1004, - // TODO - pm1_cnt_len: 32, - // TODO - sci_int: 9, ..Default::default() }; From f7146e329c3f89406aa49f05340d9c7368c4dc3f Mon Sep 17 00:00:00 2001 From: Zhang Junyu Date: Fri, 19 Jun 2026 08:44:02 +0000 Subject: [PATCH 2/2] fix: Fix cpuid --- crates/vm-core/src/virtualization/kvm/vcpu.rs | 14 +++++++++++++- .../src/virtualization/kvm/vcpu/cpu_id.rs | 19 +++++++++++++++++++ .../vm-core/src/virtualization/vcpu/error.rs | 3 +++ crates/vm-device/src/device/dummy.rs | 6 ++++-- 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 crates/vm-core/src/virtualization/kvm/vcpu/cpu_id.rs diff --git a/crates/vm-core/src/virtualization/kvm/vcpu.rs b/crates/vm-core/src/virtualization/kvm/vcpu.rs index a36fe16..0480605 100644 --- a/crates/vm-core/src/virtualization/kvm/vcpu.rs +++ b/crates/vm-core/src/virtualization/kvm/vcpu.rs @@ -21,6 +21,8 @@ use crate::virtualization::vcpu::command::VcpuCommandRequest; use crate::virtualization::vcpu::command::VcpuCommandResponse; use crate::virtualization::vcpu::error::VcpuError; +#[cfg(target_arch = "x86_64")] +mod cpu_id; mod vm_exit; pub struct KvmVcpuInternal<'a> { @@ -57,7 +59,17 @@ impl KvmVcpu { ) -> Result { let mut vcpu_fd = vm_fd.create_vcpu(vcpu_id)?; #[cfg(target_arch = "x86_64")] - vcpu_fd.set_cpuid2(supported_cpuid)?; + { + use crate::virtualization::kvm::vcpu::cpu_id::update_cpuid; + + let cpuid = update_cpuid( + supported_cpuid, + vcpu_id + .try_into() + .map_err(|_| VcpuError::UpdateCpuid("vcpu_id too large"))?, + ); + vcpu_fd.set_cpuid2(&cpuid)?; + } let (command_tx, mut command_rx) = mpsc::channel(8); let is_running = Arc::new(AtomicBool::new(false)); diff --git a/crates/vm-core/src/virtualization/kvm/vcpu/cpu_id.rs b/crates/vm-core/src/virtualization/kvm/vcpu/cpu_id.rs new file mode 100644 index 0000000..ee84103 --- /dev/null +++ b/crates/vm-core/src/virtualization/kvm/vcpu/cpu_id.rs @@ -0,0 +1,19 @@ +use kvm_bindings::CpuId; + +pub fn update_cpuid(cpuid: &CpuId, vcpu_id: u8) -> CpuId { + let mut cpuid = cpuid.clone(); + + for entry in cpuid.as_mut_slice() { + match entry.function { + // Version and Features + 0x01 => { + entry.ebx &= 0xffffff; + // Update INITIAL_APIC_ID + entry.ebx |= (vcpu_id as u32) << 24; + } + _ => continue, + } + } + + cpuid +} diff --git a/crates/vm-core/src/virtualization/vcpu/error.rs b/crates/vm-core/src/virtualization/vcpu/error.rs index 0591430..048da05 100644 --- a/crates/vm-core/src/virtualization/vcpu/error.rs +++ b/crates/vm-core/src/virtualization/vcpu/error.rs @@ -4,6 +4,9 @@ use crate::cpu::vm_exit::VmExitHandlerError; #[derive(Error, Debug)] pub enum VcpuError { + #[error("Failed to update cpuid, err: {0}")] + UpdateCpuid(&'static str), + #[error("Vcpu command channel disconnected")] VcpuCommandDisconnected, diff --git a/crates/vm-device/src/device/dummy.rs b/crates/vm-device/src/device/dummy.rs index eebae81..982ed0a 100644 --- a/crates/vm-device/src/device/dummy.rs +++ b/crates/vm-device/src/device/dummy.rs @@ -31,9 +31,11 @@ impl Device for Dummy { impl PioDevice for Dummy { fn ports(&self) -> Vec> { + let range = 0x87..0x88; + vec![ - // TODO - 0x87..0x88, + // TODO: What's this + range, ] }