From b5edcab20bb6cf38c86e2113bd75f59ae5e65982 Mon Sep 17 00:00:00 2001 From: Sebastian Ene Date: Fri, 7 Oct 2022 14:27:08 +0000 Subject: [PATCH] devices: vmwdt: Add watchdog reset reboot reason When we detect a VCPU stall we propagate the watchdog reboot error code to the event tube. The newly added error code WATCHDOG_REBOOT = 36 is returned from the crovm process. Bug: 245900797 Test: manual testing, build and Virtualization apk on a device Signed-off-by: Sebastian Ene Change-Id: Ib1ce97de911784b33d130d40536be26813edc3d7 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3936647 Reviewed-by: Daniel Verkamp --- base/src/lib.rs | 1 + devices/src/vmwdt.rs | 4 ++-- src/crosvm/sys/unix.rs | 5 +++++ src/crosvm/sys/unix/vcpu.rs | 1 + src/main.rs | 7 +++++++ src/sys/windows.rs | 5 +++++ 6 files changed, 21 insertions(+), 2 deletions(-) diff --git a/base/src/lib.rs b/base/src/lib.rs index e8685443bc..136d43f00e 100644 --- a/base/src/lib.rs +++ b/base/src/lib.rs @@ -191,4 +191,5 @@ pub enum VmEventType { Reset, Crash, Panic(u8), + WatchdogReset, } diff --git a/devices/src/vmwdt.rs b/devices/src/vmwdt.rs index 72a990a067..994632d76b 100644 --- a/devices/src/vmwdt.rs +++ b/devices/src/vmwdt.rs @@ -176,7 +176,7 @@ impl Vmwdt { } else { // The guest ran but it did not send the periodic event if let Err(_e) = - reset_evt_wrtube.send::(&VmEventType::Reset) + reset_evt_wrtube.send::(&VmEventType::WatchdogReset) { error!("failed to send reset event from vcpu {}", cpu_id) } @@ -409,7 +409,7 @@ mod tests { // Verify that our timer expired and the next_expiration_interval_ms changed match vm_evt_rdtube.recv::() { Ok(vm_event) => { - assert!(vm_event == VmEventType::Reset); + assert!(vm_event == VmEventType::WatchdogReset); } Err(_e) => { panic!(); diff --git a/src/crosvm/sys/unix.rs b/src/crosvm/sys/unix.rs index 0f7f567d96..981419aa70 100644 --- a/src/crosvm/sys/unix.rs +++ b/src/crosvm/sys/unix.rs @@ -1213,6 +1213,7 @@ pub enum ExitState { Stop, Crash, GuestPanic, + WatchdogReset, } // Remove ranges in `guest_mem_layout` that overlap with ranges in `file_backed_mappings`. // Returns the updated guest memory layout. @@ -2465,6 +2466,10 @@ fn run_control( info!("Guest reported panic [Code: {}]", pvpanic_code); break_to_wait = false; } + VmEventType::WatchdogReset => { + info!("vcpu stall detected"); + exit_state = ExitState::WatchdogReset; + } }, Err(e) => { warn!("failed to recv VmEvent: {}", e); diff --git a/src/crosvm/sys/unix/vcpu.rs b/src/crosvm/sys/unix/vcpu.rs index f42aed3e3c..c0a1595fb3 100644 --- a/src/crosvm/sys/unix/vcpu.rs +++ b/src/crosvm/sys/unix/vcpu.rs @@ -733,6 +733,7 @@ where ExitState::Crash => VmEventType::Crash, // vcpu_loop doesn't exit with GuestPanic. ExitState::GuestPanic => unreachable!(), + ExitState::WatchdogReset => VmEventType::WatchdogReset, }; if let Err(e) = vm_evt_wrtube.send::(&final_event_data) { error!( diff --git a/src/main.rs b/src/main.rs index f984521457..da10f1d0f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,6 +90,8 @@ enum CommandStatus { GuestPanic = 34, /// Invalid argument was given to crosvm. InvalidArgs = 35, + /// VM exit due to vcpu stall detection. + WatchdogReset = 36, } impl CommandStatus { @@ -100,6 +102,7 @@ impl CommandStatus { Self::VmCrash => "exiting with crash", Self::GuestPanic => "exiting with guest panic", Self::InvalidArgs => "invalid argument", + Self::WatchdogReset => "exiting with watchdog reset", } } } @@ -122,6 +125,10 @@ fn to_command_status(result: Result) -> Result { info!("crosvm has exited due to a kernel panic in guest"); Ok(CommandStatus::GuestPanic) } + Ok(sys::ExitState::WatchdogReset) => { + info!("crosvm has exited due to watchdog reboot"); + Ok(CommandStatus::WatchdogReset) + } Err(e) => { error!("crosvm has exited with error: {:#}", e); Err(e) diff --git a/src/sys/windows.rs b/src/sys/windows.rs index cf0f708b0a..20fdfb5cfa 100644 --- a/src/sys/windows.rs +++ b/src/sys/windows.rs @@ -233,6 +233,7 @@ pub enum ExitState { Crash, #[allow(dead_code)] GuestPanic, + WatchdogReset, } type DeviceResult = Result; @@ -966,6 +967,10 @@ fn run_control( VmEventType::Panic(_) => { error!("got pvpanic event. this event is not expected on Windows."); } + VmEventType::WatchdogReset => { + info!("vcpu stall detected"); + exit_state = ExitState::WatchdogReset; + } } break 'poll; }