Merge "Revert "gen_rpc -> require_rpc""
diff --git a/authfs/Android.bp b/authfs/Android.bp
index ef78d4e..935ed5c 100644
--- a/authfs/Android.bp
+++ b/authfs/Android.bp
@@ -63,7 +63,7 @@
 rust_test {
     name: "authfs_device_test_src_lib",
     defaults: ["authfs_defaults"],
-    test_suites: ["device-tests"],
+    test_suites: ["general-tests"],
     data: [":authfs_test_files"],
 }
 
diff --git a/compos/Android.bp b/compos/Android.bp
index 0bcbcdd..d4fccbb 100644
--- a/compos/Android.bp
+++ b/compos/Android.bp
@@ -49,5 +49,5 @@
 rust_test {
     name: "compsvc_device_tests",
     defaults: ["compsvc_defaults"],
-    test_suites: ["device-tests"],
+    test_suites: ["general-tests"],
 }
diff --git a/compos/common/compos_client.rs b/compos/common/compos_client.rs
index 6a35fb0..72d2b76 100644
--- a/compos/common/compos_client.rs
+++ b/compos/common/compos_client.rs
@@ -37,6 +37,7 @@
 };
 use compos_aidl_interface::aidl::com::android::compos::ICompOsService::ICompOsService;
 use log::{info, warn};
+use rustutils::system_properties;
 use std::fs::File;
 use std::io::{BufRead, BufReader};
 use std::num::NonZeroU32;
@@ -86,6 +87,8 @@
         idsig_manifest_apk: &Path,
         parameters: &VmParameters,
     ) -> Result<VmInstance> {
+        let protected_vm = want_protected_vm()?;
+
         let instance_fd = ParcelFileDescriptor::new(instance_image);
 
         let apex_dir = Path::new(COMPOS_APEX_ROOT);
@@ -109,7 +112,9 @@
                 .context("Failed to create system log file")?;
             let console_fd = ParcelFileDescriptor::new(console_fd);
             let log_fd = ParcelFileDescriptor::new(log_fd);
-            (Some(console_fd), Some(log_fd), DebugLevel::FULL)
+            // Full debug is not available in a protected VM
+            let debug_level = if protected_vm { DebugLevel::APP_ONLY } else { DebugLevel::FULL };
+            (Some(console_fd), Some(log_fd), debug_level)
         } else {
             (None, None, DebugLevel::NONE)
         };
@@ -122,7 +127,7 @@
             configPath: config_path.to_owned(),
             debugLevel: debug_level,
             extraIdsigs: vec![idsig_manifest_apk_fd],
-            protectedVm: false,
+            protectedVm: protected_vm,
             memoryMib: VM_MEMORY_MIB,
             numCpus: parameters.cpus.map_or(1, NonZeroU32::get) as i32,
             cpuAffinity: parameters.cpu_set.clone(),
@@ -193,6 +198,31 @@
     Ok(idsig_fd)
 }
 
+fn want_protected_vm() -> Result<bool> {
+    let have_protected_vm =
+        system_properties::read_bool("ro.boot.hypervisor.protected_vm.supported", false)
+            .unwrap_or(false);
+    if have_protected_vm {
+        info!("Starting protected VM");
+        return Ok(true);
+    }
+
+    let build_type = system_properties::read("ro.build.type")?;
+    let is_debug_build = matches!(build_type.as_str(), "userdebug" | "eng");
+    if !is_debug_build {
+        bail!("Protected VM not supported, unable to start VM");
+    }
+
+    let have_unprotected_vm =
+        system_properties::read_bool("ro.boot.hypervisor.vm.supported", false).unwrap_or(false);
+    if have_unprotected_vm {
+        warn!("Protected VM not supported, falling back to unprotected on {} build", build_type);
+        return Ok(false);
+    }
+
+    bail!("No VM support available")
+}
+
 struct VsockFactory<'a> {
     vm: &'a dyn IVirtualMachine,
 }
diff --git a/compos/common/timeouts.rs b/compos/common/timeouts.rs
index 42cfe69..c86ae34 100644
--- a/compos/common/timeouts.rs
+++ b/compos/common/timeouts.rs
@@ -53,7 +53,7 @@
     // Note: the source of truth for these odrefresh timeouts is art/odrefresh/odr_config.h.
     odrefresh_max_execution_time: Duration::from_secs(300),
     odrefresh_max_child_process_time: Duration::from_secs(90),
-    vm_max_time_to_ready: Duration::from_secs(10),
+    vm_max_time_to_ready: Duration::from_secs(15),
 };
 
 /// The timeouts that we use when need_extra_time() returns true.
diff --git a/compos/composd/src/composd_main.rs b/compos/composd/src/composd_main.rs
index 235c107..d1b711d 100644
--- a/compos/composd/src/composd_main.rs
+++ b/compos/composd/src/composd_main.rs
@@ -29,6 +29,7 @@
 use anyhow::{Context, Result};
 use compos_common::compos_client::VmInstance;
 use log::{error, info};
+use std::panic;
 use std::sync::Arc;
 
 fn try_main() -> Result<()> {
@@ -38,6 +39,11 @@
         android_logger::Config::default().with_tag("composd").with_min_level(log_level),
     );
 
+    // Redirect panic messages to logcat.
+    panic::set_hook(Box::new(|panic_info| {
+        log::error!("{}", panic_info);
+    }));
+
     ProcessState::start_thread_pool();
 
     let virtualization_service = VmInstance::connect_to_virtualization_service()?;
diff --git a/compos/src/compilation.rs b/compos/src/compilation.rs
index 48ba4a6..ae4a29d 100644
--- a/compos/src/compilation.rs
+++ b/compos/src/compilation.rs
@@ -62,7 +62,9 @@
         system_server_compiler_filter: &'a str,
     ) -> Result<Self> {
         if compilation_mode != CompilationMode::NORMAL_COMPILE {
-            let debuggable = system_properties::read_bool("ro.boot.microdroid.debuggable", false)?;
+            let debuggable = is_property_set("ro.boot.microdroid.debuggable")
+                || is_property_set("ro.boot.logd.enabled")
+                || is_property_set("ro.boot.adb.enabled");
             if !debuggable {
                 bail!("Requested compilation mode only available in debuggable VMs");
             }
@@ -97,6 +99,12 @@
     }
 }
 
+// Return whether the named property is definitely enabled. Deliberately conservative; returns
+// false if the property does not exist or cannot be read or is malformed.
+fn is_property_set(name: &str) -> bool {
+    system_properties::read_bool(name, false).unwrap_or(false)
+}
+
 pub fn odrefresh(
     odrefresh_path: &Path,
     context: OdrefreshContext,
diff --git a/compos/src/compsvc_main.rs b/compos/src/compsvc_main.rs
index c2923f0..ebb5514 100644
--- a/compos/src/compsvc_main.rs
+++ b/compos/src/compsvc_main.rs
@@ -38,6 +38,7 @@
 use binder_common::rpc_server::run_rpc_server;
 use compos_common::COMPOS_VSOCK_PORT;
 use log::{debug, error};
+use std::panic;
 
 /// The CID representing the host VM
 const VMADDR_CID_HOST: u32 = 2;
@@ -59,6 +60,10 @@
         android_logger::init_once(
             android_logger::Config::default().with_tag("compsvc").with_min_level(log::Level::Debug),
         );
+        // Redirect panic messages to logcat.
+        panic::set_hook(Box::new(|panic_info| {
+            log::error!("{}", panic_info);
+        }));
     }
 
     let service = compsvc::new_binder()?.as_binder();
diff --git a/compos/tests/java/android/compos/test/ComposTestCase.java b/compos/tests/java/android/compos/test/ComposTestCase.java
index ff3baa2..1213ada 100644
--- a/compos/tests/java/android/compos/test/ComposTestCase.java
+++ b/compos/tests/java/android/compos/test/ComposTestCase.java
@@ -38,6 +38,8 @@
     // Binaries used in test. (These paths are valid both in host and Microdroid.)
     private static final String ODREFRESH_BIN = "/apex/com.android.art/bin/odrefresh";
     private static final String COMPOSD_CMD_BIN = "/apex/com.android.compos/bin/composd_cmd";
+    private static final String COMPOS_VERIFY_KEY_BIN =
+            "/apex/com.android.compos/bin/compos_verify_key";
 
     /** Output directory of odrefresh */
     private static final String TEST_ARTIFACTS_DIR = "test-artifacts";
@@ -148,8 +150,11 @@
         assertThat(actualChecksumSnapshot).isEqualTo(expectedChecksumSnapshot);
 
         // Expect extra files generated by CompOS exist.
-        android.assumeSuccess("test -f " + ODREFRESH_OUTPUT_DIR + "/compos.info");
-        android.assumeSuccess("test -f " + ODREFRESH_OUTPUT_DIR + "/compos.info.signature");
+        android.run("test -f " + ODREFRESH_OUTPUT_DIR + "/compos.info");
+        android.run("test -f " + ODREFRESH_OUTPUT_DIR + "/compos.info.signature");
+
+        // Expect the CompOS public key & key blob to be valid
+        android.run(COMPOS_VERIFY_KEY_BIN + " --debug --instance test");
     }
 
     private CommandResult runOdrefresh(CommandRunner android, String command) throws Exception {
diff --git a/compos/verify_key/verify_key.rs b/compos/verify_key/verify_key.rs
index 13d3c8b..9454442 100644
--- a/compos/verify_key/verify_key.rs
+++ b/compos/verify_key/verify_key.rs
@@ -27,6 +27,7 @@
 };
 use std::fs::{self, File};
 use std::io::Read;
+use std::panic;
 use std::path::{Path, PathBuf};
 
 const MAX_FILE_SIZE_BYTES: u64 = 8 * 1024;
@@ -38,6 +39,11 @@
             .with_min_level(log::Level::Info),
     );
 
+    // Redirect panic messages to logcat.
+    panic::set_hook(Box::new(|panic_info| {
+        log::error!("{}", panic_info);
+    }));
+
     if let Err(e) = try_main() {
         log::error!("{:?}", e);
         std::process::exit(-1)
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
index df3ad37..a49c9be 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
@@ -60,11 +60,13 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
         DEATH_REASON_VIRTUALIZATIONSERVICE_DIED,
-        DEATH_REASON_SHUTDOWN,
-        DEATH_REASON_REBOOT,
+        DEATH_REASON_INFRASTRUCTURE_ERROR,
         DEATH_REASON_KILLED,
         DEATH_REASON_UNKNOWN,
-        DEATH_REASON_INFRASTRUCTURE_ERROR
+        DEATH_REASON_SHUTDOWN,
+        DEATH_REASON_ERROR,
+        DEATH_REASON_REBOOT,
+        DEATH_REASON_CRASH
     })
     @interface DeathReason {}
 
@@ -74,20 +76,26 @@
      */
     int DEATH_REASON_VIRTUALIZATIONSERVICE_DIED = -1;
 
-    /** The VM requested to shut down. */
-    int DEATH_REASON_SHUTDOWN = 0;
-
-    /** The VM requested to reboot, possibly as the result of a kernel panic. */
-    int DEATH_REASON_REBOOT = 1;
+    /** There was an error waiting for the VM. */
+    int DEATH_REASON_INFRASTRUCTURE_ERROR = 0;
 
     /** The VM was killed. */
-    int DEATH_REASON_KILLED = 2;
+    int DEATH_REASON_KILLED = 1;
 
     /** The VM died for an unknown reason. */
-    int DEATH_REASON_UNKNOWN = 3;
+    int DEATH_REASON_UNKNOWN = 2;
 
-    /** There was an error waiting for the VM. */
-    int DEATH_REASON_INFRASTRUCTURE_ERROR = 4;
+    /** The VM requested to shut down. */
+    int DEATH_REASON_SHUTDOWN = 3;
+
+    /** crosvm had an error starting the VM. */
+    int DEATH_REASON_ERROR = 4;
+
+    /** The VM requested to reboot, possibly as the result of a kernel panic. */
+    int DEATH_REASON_REBOOT = 5;
+
+    /** The VM or crosvm crashed. */
+    int DEATH_REASON_CRASH = 6;
 
     /** Called when the payload starts in the VM. */
     void onPayloadStarted(@NonNull VirtualMachine vm, @Nullable ParcelFileDescriptor stream);
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
index 04a90e0..35d600a 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -206,6 +206,9 @@
             // TODO(jiyong): should we treat APP_ONLY and FULL the same?
             return false;
         }
+        if (this.mProtectedVm != other.mProtectedVm) {
+            return false;
+        }
         return true;
     }
 
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 3566bd2..7384cef 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -518,11 +518,6 @@
 prebuilt_etc {
     name: "microdroid_uboot_env",
     src: ":microdroid_uboot_env_gen",
-    arch: {
-        x86_64: {
-            src: ":microdroid_uboot_env_gen_x86_64",
-        },
-    },
     filename: "uboot_env.img",
 }
 
@@ -546,26 +541,6 @@
         "--image $(out)",
 }
 
-genrule {
-    name: "microdroid_uboot_env_gen_x86_64",
-    tools: [
-        "mkenvimage_host",
-        "avbtool",
-    ],
-    srcs: [
-        "uboot-env-x86_64.txt",
-        ":microdroid_sign_key",
-    ],
-    out: ["output.img"],
-    cmd: "$(location mkenvimage_host) -s 4096 -o $(out) $(location uboot-env-x86_64.txt) && " +
-        "$(location avbtool) add_hash_footer " +
-        "--algorithm SHA256_RSA4096 " +
-        "--partition_name uboot_env " +
-        "--key $(location :microdroid_sign_key) " +
-        "--partition_size $$(( " + avb_hash_footer_kb + " * 1024 + ( $$(stat --format=%s $(out)) + 4096 - 1 ) / 4096 * 4096 )) " +
-        "--image $(out)",
-}
-
 // Note that keys can be different for filesystem images even though we're using the same key
 // for microdroid. However, the key signing VBmeta should match with the pubkey embedded in
 // bootloader.
diff --git a/microdroid/uboot-env-x86_64.txt b/microdroid/uboot-env-x86_64.txt
deleted file mode 100644
index 07a9b18..0000000
--- a/microdroid/uboot-env-x86_64.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-# Static u-boot environment variables for microdroid. See b/180481192
-
-# Boot the device following the Android boot procedure
-# `0` is the disk number of os_composite.img
-# `a` and `_a` are the slot index for A/B
-bootcmd=verified_boot_android virtio 0 a
-
-bootdelay=0
-
-# U-Boot in x86_64 by defaults loads kernel at 0x20000000 (512MB), which is
-# out of the physical memory when the VM is launched with the default memory
-# size of 256MB. To avoid that, explicitly set the kernel load addresss using
-# loadaddr variable.
-loadaddr=0x02000000
-fdtaddr=0x40000000
-
-# Microdroid doesn't use keymint yet
-android_keymint_needed=N
diff --git a/microdroid/uboot-env.txt b/microdroid/uboot-env.txt
index 0385b50..e5f8b79 100644
--- a/microdroid/uboot-env.txt
+++ b/microdroid/uboot-env.txt
@@ -1,12 +1 @@
-# Static u-boot environment variables for microdroid. See b/180481192
-
-# Boot the device following the Android boot procedure
-# `0` is the disk number of os_composite.img
-# `a` and `_a` are the slot index for A/B
-bootcmd=verified_boot_android virtio 0 a
-
-bootdelay=0
-fdtaddr=0x80000000
-
-# Microdroid doesn't use keymint yet
-android_keymint_needed=N
+# Empty environment for bootloader debugging
diff --git a/microdroid_manager/Android.bp b/microdroid_manager/Android.bp
index 1878c87..e4827aa 100644
--- a/microdroid_manager/Android.bp
+++ b/microdroid_manager/Android.bp
@@ -62,7 +62,7 @@
 rust_test {
     name: "microdroid_manager_test",
     defaults: ["microdroid_manager_defaults"],
-    test_suites: ["device-tests"],
+    test_suites: ["general-tests"],
     rustlibs: [
         "libtempfile",
     ],
diff --git a/tests/Android.bp b/tests/Android.bp
index 8cfefcc..cf720f1 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -23,7 +23,7 @@
 
 cc_test {
     name: "VirtualizationTestCases",
-    test_suites: ["device-tests"],
+    test_suites: ["general-tests"],
     srcs: [
         "common.cc",
         "vsock_test.cc",
@@ -38,6 +38,7 @@
         // The existence of the library in the system partition is not guaranteed.
         // Let's have our own copy of it.
         "android.system.virtualizationservice-cpp",
+        "PlatformProperties",
     ],
     shared_libs: [
         "libbase",
diff --git a/tests/hostside/Android.bp b/tests/hostside/Android.bp
index 968c991..d1318b5 100644
--- a/tests/hostside/Android.bp
+++ b/tests/hostside/Android.bp
@@ -5,7 +5,7 @@
 java_test_host {
     name: "MicrodroidHostTestCases",
     srcs: ["java/**/*.java"],
-    test_suites: ["device-tests"],
+    test_suites: ["general-tests"],
     libs: [
         "tradefed",
     ],
diff --git a/tests/hostside/helper/Android.bp b/tests/hostside/helper/Android.bp
index 48dbcac..aa748ab 100644
--- a/tests/hostside/helper/Android.bp
+++ b/tests/hostside/helper/Android.bp
@@ -7,7 +7,7 @@
     host_supported: true,
     device_supported: false,
     srcs: ["java/**/*.java"],
-    test_suites: ["device-tests"],
+    test_suites: ["general-tests"],
     libs: [
         "tradefed",
         "compatibility-tradefed",
diff --git a/tests/testapk/Android.bp b/tests/testapk/Android.bp
index 40d72fe..7dca024 100644
--- a/tests/testapk/Android.bp
+++ b/tests/testapk/Android.bp
@@ -4,7 +4,7 @@
 
 android_test {
     name: "MicrodroidTestApp",
-    test_suites: ["device-tests"],
+    test_suites: ["general-tests"],
     srcs: ["src/java/**/*.java"],
     static_libs: [
         "androidx.test.runner",
diff --git a/tests/vsock_test.cc b/tests/vsock_test.cc
index 0b863a9..9550651 100644
--- a/tests/vsock_test.cc
+++ b/tests/vsock_test.cc
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <android/sysprop/HypervisorProperties.sysprop.h>
 #include <linux/kvm.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
@@ -48,15 +49,26 @@
 static constexpr const char kVmParams[] = "rdinit=/bin/init bin/vsock_client 2 45678 HelloWorld";
 static constexpr const char kTestMessage[] = "HelloWorld";
 
-/** Returns true if the kernel supports Protected KVM. */
-bool isPkvmSupported() {
-    unique_fd kvm_fd(open("/dev/kvm", O_NONBLOCK | O_CLOEXEC));
-    return kvm_fd != 0 && ioctl(kvm_fd, KVM_CHECK_EXTENSION, KVM_CAP_ARM_PROTECTED_VM) == 1;
+/** Returns true if the kernel supports protected VMs. */
+bool isProtectedVmSupported() {
+    return android::sysprop::HypervisorProperties::hypervisor_protected_vm_supported().value_or(
+            false);
+}
+
+/** Returns true if the kernel supports unprotected VMs. */
+bool isUnprotectedVmSupported() {
+    return android::sysprop::HypervisorProperties::hypervisor_vm_supported().value_or(false);
 }
 
 void runTest(sp<IVirtualizationService> virtualization_service, bool protected_vm) {
-    if (protected_vm && !isPkvmSupported()) {
-        GTEST_SKIP() << "Skipping as pKVM is not supported on this device.";
+    if (protected_vm) {
+        if (!isProtectedVmSupported()) {
+            GTEST_SKIP() << "Skipping as protected VMs are not supported on this device.";
+        }
+    } else {
+        if (!isUnprotectedVmSupported()) {
+            GTEST_SKIP() << "Skipping as unprotected VMs are not supported on this device.";
+        }
     }
 
     binder::Status status;
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
index 2f454a9..d736f1b 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
@@ -20,14 +20,18 @@
  */
 @Backing(type="int")
 enum DeathReason {
-    /** The VM requested to shut down. */
-    SHUTDOWN = 0,
-    /** The VM requested to reboot, possibly as the result of a kernel panic. */
-    REBOOT = 1,
-    /** The VM was killed. */
-    KILLED = 2,
-    /** The VM died for an unknown reason. */
-    UNKNOWN = 3,
     /** There was an error waiting for the VM. */
-    INFRASTRUCTURE_ERROR = 4,
+    INFRASTRUCTURE_ERROR = 0,
+    /** The VM was killed. */
+    KILLED = 1,
+    /** The VM died for an unknown reason. */
+    UNKNOWN = 2,
+    /** The VM requested to shut down. */
+    SHUTDOWN = 3,
+    /** crosvm had an error starting the VM. */
+    ERROR = 4,
+    /** The VM requested to reboot, possibly as the result of a kernel panic. */
+    REBOOT = 5,
+    /** The VM or crosvm crashed. */
+    CRASH = 6,
 }
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 5b0c9b7..ebb01b3 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -50,7 +50,7 @@
 use binder_common::{lazy_service::LazyServiceGuard, new_binder_exception};
 use disk::QcowFile;
 use idsig::{HashAlgorithm, V4Signature};
-use log::{debug, error, info, warn};
+use log::{debug, error, info, warn, trace};
 use microdroid_payload_config::VmPayloadConfig;
 use rustutils::system_properties;
 use statslog_virtualization_rust::vm_creation_requested::{stats_write, Hypervisor};
@@ -440,9 +440,9 @@
 fn write_vm_creation_stats(protected: bool, success: bool) {
     match stats_write(Hypervisor::Pkvm, protected, success) {
         Err(e) => {
-            info!("stastlog_rust fails with error: {}", e);
+            warn!("statslog_rust failed with error: {}", e);
         }
-        Ok(_) => info!("stastlog_rust succeeded for virtualization service"),
+        Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
     }
 }
 
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
index 76f4f47..352ed50 100644
--- a/virtualizationservice/src/crosvm.rs
+++ b/virtualizationservice/src/crosvm.rs
@@ -36,8 +36,12 @@
 
 const CROSVM_PATH: &str = "/apex/com.android.virt/bin/crosvm";
 
+/// The exit status which crosvm returns when it has an error starting a VM.
+const CROSVM_ERROR_STATUS: i32 = 1;
 /// The exit status which crosvm returns when a VM requests a reboot.
 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;
 
 /// Configuration for a VM to run with crosvm.
 #[derive(Debug)]
@@ -243,7 +247,9 @@
         match status.code() {
             None => DeathReason::KILLED,
             Some(0) => DeathReason::SHUTDOWN,
+            Some(CROSVM_ERROR_STATUS) => DeathReason::ERROR,
             Some(CROSVM_REBOOT_STATUS) => DeathReason::REBOOT,
+            Some(CROSVM_CRASH_STATUS) => DeathReason::CRASH,
             Some(_) => DeathReason::UNKNOWN,
         }
     } else {
@@ -265,7 +271,8 @@
         .arg(config.cid.to_string());
 
     if config.protected {
-        command.arg("--protected-vm");
+        // TODO: Go back to "--protected-vm" once pVM firmware is fixed.
+        command.arg("--protected-vm-without-firmware");
     }
 
     if let Some(memory_mib) = config.memory_mib {
diff --git a/vm/src/run.rs b/vm/src/run.rs
index d558add..6a0fc15 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -293,11 +293,13 @@
         self.dead.raise();
 
         match reason {
-            DeathReason::SHUTDOWN => println!("VM shutdown cleanly."),
-            DeathReason::REBOOT => println!("VM tried to reboot, possibly due to a kernel panic."),
+            DeathReason::INFRASTRUCTURE_ERROR => println!("Error waiting for VM to finish."),
             DeathReason::KILLED => println!("VM was killed."),
             DeathReason::UNKNOWN => println!("VM died for an unknown reason."),
-            DeathReason::INFRASTRUCTURE_ERROR => println!("Error waiting for VM to finish."),
+            DeathReason::SHUTDOWN => println!("VM shutdown cleanly."),
+            DeathReason::ERROR => println!("Error starting VM."),
+            DeathReason::REBOOT => println!("VM tried to reboot, possibly due to a kernel panic."),
+            DeathReason::CRASH => println!("VM crashed."),
             _ => println!("VM died for an unrecognised reason."),
         }
         Ok(())