Skip to content

Commit 51e84a4

Browse files
committed
efi: Implement reset_system for Cloud Hypervisor
The ResetSystem runtime service was intentionally left as a no-op to force Linux to use ACPI for shutdown. However, Windows calls ResetSystem(EfiResetShutdown) as its final shutdown step and does not fall back to ACPI when the call returns. This causes the Cloud Hypervisor process to hang indefinitely after Windows shuts down. Write the appropriate value to Cloud Hypervisor's shutdown I/O port (0x600) based on the reset type: - EfiResetShutdown: SLP_TYP=5 + SLP_EN (triggers VM exit) - EfiResetCold/Warm: reboot value (triggers VM reset) Linux guests are unaffected as they use ACPI directly. Fixes: #422 Signed-off-by: CMGS <ilskdw@gmail.com>
1 parent 286a40e commit 51e84a4

1 file changed

Lines changed: 24 additions & 2 deletions

File tree

src/efi/runtime_services.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,30 @@ pub extern "efiapi" fn get_next_high_mono_count(_: *mut u32) -> Status {
196196
Status::DEVICE_ERROR
197197
}
198198

199-
pub extern "efiapi" fn reset_system(_: ResetType, _: Status, _: usize, _: *mut c_void) {
200-
// Don't do anything to force the kernel to use ACPI for shutdown and triple-fault for reset
199+
pub extern "efiapi" fn reset_system(_reset_type: ResetType, _: Status, _: usize, _: *mut c_void) {
200+
#[cfg(target_arch = "x86_64")]
201+
{
202+
// Cloud Hypervisor's AcpiShutdownDevice is at IO port 0x600.
203+
const SHUTDOWN_PORT: u16 = 0x600;
204+
const S5_SLEEP_VALUE: u8 = (5 << 2) | (1 << 5); // SLP_TYP=5, SLP_EN=1
205+
const REBOOT_VALUE: u8 = 1;
206+
207+
let value = if _reset_type == efi::RESET_SHUTDOWN {
208+
S5_SLEEP_VALUE
209+
} else {
210+
REBOOT_VALUE
211+
};
212+
unsafe {
213+
core::arch::asm!("out dx, al", in("dx") SHUTDOWN_PORT, in("al") value);
214+
}
215+
}
216+
217+
loop {
218+
#[cfg(target_arch = "x86_64")]
219+
unsafe {
220+
core::arch::asm!("hlt");
221+
}
222+
}
201223
}
202224

203225
pub extern "efiapi" fn update_capsule(

0 commit comments

Comments
 (0)