Report crosvm reboot reason on watchdog stall

Monitor the crosvm exist code and look for the WATCHDOG_REBOOT(36).
When this is detected, invoke callback_on_died to propagate the exit code.
This crosvm return code is generated when a VCPU stall is detected.

Bug: 245900797
Test: manual verification with a patched crosvm that returns
 WATCHDOG_REBOOT on vmwdt.rs instantiation.
deliver on stderr.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Change-Id: I4bea374f96fa08338d3830dce97e5b9531fb5e91
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
index dceabf1..416eb7b 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
@@ -54,4 +54,6 @@
     MICRODROID_UNKNOWN_RUNTIME_ERROR = 15,
     /** The VM killed due to hangup */
     HANGUP = 16,
+    /** The VCPU stalled */
+    WATCHDOG_REBOOT = 17,
 }
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
index 4a9df46..72af431 100644
--- a/virtualizationservice/src/crosvm.rs
+++ b/virtualizationservice/src/crosvm.rs
@@ -55,6 +55,8 @@
 const CROSVM_REBOOT_STATUS: i32 = 32;
 /// The exit status which crosvm returns when it crashes due to an error.
 const CROSVM_CRASH_STATUS: i32 = 33;
+/// The exit status which crosvm returns when vcpu is stalled.
+const CROSVM_WATCHDOG_REBOOT_STATUS: i32 = 36;
 
 lazy_static! {
     /// If the VM doesn't move to the Started state within this amount time, a hang-up error is
@@ -243,7 +245,14 @@
         let result = child.wait();
         match &result {
             Err(e) => error!("Error waiting for crosvm({}) instance to die: {}", child.id(), e),
-            Ok(status) => info!("crosvm({}) exited with status {}", child.id(), status),
+            Ok(status) => {
+                info!("crosvm({}) exited with status {}", child.id(), status);
+                if let Some(exit_status_code) = status.code() {
+                    if exit_status_code == CROSVM_WATCHDOG_REBOOT_STATUS {
+                        info!("detected vcpu stall on crosvm");
+                    }
+                }
+            }
         }
 
         let mut vm_state = self.vm_state.lock().unwrap();
@@ -417,6 +426,7 @@
             Some(CROSVM_ERROR_STATUS) => DeathReason::ERROR,
             Some(CROSVM_REBOOT_STATUS) => DeathReason::REBOOT,
             Some(CROSVM_CRASH_STATUS) => DeathReason::CRASH,
+            Some(CROSVM_WATCHDOG_REBOOT_STATUS) => DeathReason::WATCHDOG_REBOOT,
             Some(_) => DeathReason::UNKNOWN,
         }
     } else {