Merge "Map PCI CAM MMIO region and register pages with the MMIO guard."
diff --git a/javalib/Android.bp b/javalib/Android.bp
index 71287f2..3f957d2 100644
--- a/javalib/Android.bp
+++ b/javalib/Android.bp
@@ -13,8 +13,7 @@
 java_sdk_library {
     name: "framework-virtualization",
 
-    // TODO(b/243512044): introduce non-updatable-framework-module-defaults
-    defaults: ["framework-module-defaults"],
+    defaults: ["non-updatable-framework-module-defaults"],
 
     jarjar_rules: "jarjar-rules.txt",
 
@@ -41,11 +40,6 @@
         ],
     },
 
-    test: {
-        enabled: true,
-        sdk_version: "module_current",
-    },
-
     sdk_version: "core_platform",
     stub_only_libs: [
         "android_module_lib_stubs_current",
diff --git a/javalib/api/system-current.txt b/javalib/api/system-current.txt
index f38d8fd..f364f4c 100644
--- a/javalib/api/system-current.txt
+++ b/javalib/api/system-current.txt
@@ -38,7 +38,6 @@
     field public static final int STOP_REASON_BOOTLOADER_INSTANCE_IMAGE_CHANGED = 10; // 0xa
     field public static final int STOP_REASON_BOOTLOADER_PUBLIC_KEY_MISMATCH = 9; // 0x9
     field public static final int STOP_REASON_CRASH = 6; // 0x6
-    field public static final int STOP_REASON_ERROR = 4; // 0x4
     field public static final int STOP_REASON_HANGUP = 16; // 0x10
     field public static final int STOP_REASON_INFRASTRUCTURE_ERROR = 0; // 0x0
     field public static final int STOP_REASON_KILLED = 1; // 0x1
@@ -51,6 +50,7 @@
     field public static final int STOP_REASON_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH = 7; // 0x7
     field public static final int STOP_REASON_REBOOT = 5; // 0x5
     field public static final int STOP_REASON_SHUTDOWN = 3; // 0x3
+    field public static final int STOP_REASON_START_FAILED = 4; // 0x4
     field public static final int STOP_REASON_UNKNOWN = 2; // 0x2
     field public static final int STOP_REASON_VIRTUALIZATION_SERVICE_DIED = -1; // 0xffffffff
   }
diff --git a/javalib/api/test-current.txt b/javalib/api/test-current.txt
index 42ad060..8b7ec11 100644
--- a/javalib/api/test-current.txt
+++ b/javalib/api/test-current.txt
@@ -1,6 +1,10 @@
 // Signature format: 2.0
 package android.system.virtualmachine {
 
+  public class VirtualMachine implements java.lang.AutoCloseable {
+    method @NonNull public java.io.File getRootDir();
+  }
+
   public final class VirtualMachineConfig {
     method @Nullable public String getPayloadConfigPath();
   }
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index 63b5628..b8be703 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -26,7 +26,6 @@
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_BOOTLOADER_INSTANCE_IMAGE_CHANGED;
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_BOOTLOADER_PUBLIC_KEY_MISMATCH;
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_CRASH;
-import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_ERROR;
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_HANGUP;
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_INFRASTRUCTURE_ERROR;
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_KILLED;
@@ -39,6 +38,7 @@
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH;
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_REBOOT;
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_SHUTDOWN;
+import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_START_FAILED;
 import static android.system.virtualmachine.VirtualMachineCallback.STOP_REASON_UNKNOWN;
 
 import static java.util.Objects.requireNonNull;
@@ -49,6 +49,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -984,6 +985,18 @@
     }
 
     /**
+     * Returns the root directory where all files related to this {@link VirtualMachine} (e.g.
+     * {@code instance.img}, {@code apk.idsig}, etc) are stored.
+     *
+     * @hide
+     */
+    @TestApi
+    @NonNull
+    public File getRootDir() {
+        return mVmRootPath;
+    }
+
+    /**
      * Captures the current state of the VM in a {@link VirtualMachineDescriptor} instance. The VM
      * needs to be stopped to avoid inconsistency in its state representation.
      *
@@ -1034,8 +1047,8 @@
                 return STOP_REASON_KILLED;
             case DeathReason.SHUTDOWN:
                 return STOP_REASON_SHUTDOWN;
-            case DeathReason.ERROR:
-                return STOP_REASON_ERROR;
+            case DeathReason.START_FAILED:
+                return STOP_REASON_START_FAILED;
             case DeathReason.REBOOT:
                 return STOP_REASON_REBOOT;
             case DeathReason.CRASH:
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
index f3c4831..fad2fa9 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
@@ -58,26 +58,28 @@
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "STOP_REASON_", value = {
-        STOP_REASON_VIRTUALIZATION_SERVICE_DIED,
-        STOP_REASON_INFRASTRUCTURE_ERROR,
-        STOP_REASON_KILLED,
-        STOP_REASON_UNKNOWN,
-        STOP_REASON_SHUTDOWN,
-        STOP_REASON_ERROR,
-        STOP_REASON_REBOOT,
-        STOP_REASON_CRASH,
-        STOP_REASON_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH,
-        STOP_REASON_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED,
-        STOP_REASON_BOOTLOADER_PUBLIC_KEY_MISMATCH,
-        STOP_REASON_BOOTLOADER_INSTANCE_IMAGE_CHANGED,
-        STOP_REASON_MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE,
-        STOP_REASON_MICRODROID_PAYLOAD_HAS_CHANGED,
-        STOP_REASON_MICRODROID_PAYLOAD_VERIFICATION_FAILED,
-        STOP_REASON_MICRODROID_INVALID_PAYLOAD_CONFIG,
-        STOP_REASON_MICRODROID_UNKNOWN_RUNTIME_ERROR,
-        STOP_REASON_HANGUP,
-    })
+    @IntDef(
+            prefix = "STOP_REASON_",
+            value = {
+                STOP_REASON_VIRTUALIZATION_SERVICE_DIED,
+                STOP_REASON_INFRASTRUCTURE_ERROR,
+                STOP_REASON_KILLED,
+                STOP_REASON_UNKNOWN,
+                STOP_REASON_SHUTDOWN,
+                STOP_REASON_START_FAILED,
+                STOP_REASON_REBOOT,
+                STOP_REASON_CRASH,
+                STOP_REASON_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH,
+                STOP_REASON_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED,
+                STOP_REASON_BOOTLOADER_PUBLIC_KEY_MISMATCH,
+                STOP_REASON_BOOTLOADER_INSTANCE_IMAGE_CHANGED,
+                STOP_REASON_MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE,
+                STOP_REASON_MICRODROID_PAYLOAD_HAS_CHANGED,
+                STOP_REASON_MICRODROID_PAYLOAD_VERIFICATION_FAILED,
+                STOP_REASON_MICRODROID_INVALID_PAYLOAD_CONFIG,
+                STOP_REASON_MICRODROID_UNKNOWN_RUNTIME_ERROR,
+                STOP_REASON_HANGUP,
+            })
     @interface StopReason {}
 
     /** The virtualization service itself died, taking the VM down with it. */
@@ -98,7 +100,7 @@
     int STOP_REASON_SHUTDOWN = 3;
 
     /** crosvm had an error starting the VM. */
-    int STOP_REASON_ERROR = 4;
+    int STOP_REASON_START_FAILED = 4;
 
     /** The VM requested to reboot, possibly as the result of a kernel panic. */
     int STOP_REASON_REBOOT = 5;
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 35b9e61..57703f3 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -325,6 +325,52 @@
     }
 
     @Test
+    @CddTest(requirements = {"9.17/C-1-1"})
+    public void vmFilesStoredInDeDirWhenCreatedFromDEContext() throws Exception {
+        final Context ctx = getContext().createDeviceProtectedStorageContext();
+        final int userId = ctx.getUserId();
+        final VirtualMachineManager vmm = ctx.getSystemService(VirtualMachineManager.class);
+        VirtualMachineConfig config =
+                newVmConfigBuilder().setPayloadBinaryPath("binary/path").build();
+        try {
+            VirtualMachine vm = vmm.create("vm-name", config);
+            // TODO(b/261430346): what about non-primary user?
+            assertThat(vm.getRootDir().getAbsolutePath())
+                    .isEqualTo(
+                            "/data/user_de/" + userId + "/com.android.microdroid.test/vm/vm-name");
+        } finally {
+            vmm.delete("vm-name");
+        }
+    }
+
+    @Test
+    @CddTest(requirements = {"9.17/C-1-1"})
+    public void vmFilesStoredInCeDirWhenCreatedFromCEContext() throws Exception {
+        final Context ctx = getContext().createCredentialProtectedStorageContext();
+        final int userId = ctx.getUserId();
+        final VirtualMachineManager vmm = ctx.getSystemService(VirtualMachineManager.class);
+        VirtualMachineConfig config =
+                newVmConfigBuilder().setPayloadBinaryPath("binary/path").build();
+        try {
+            VirtualMachine vm = vmm.create("vm-name", config);
+            // TODO(b/261430346): what about non-primary user?
+            assertThat(vm.getRootDir().getAbsolutePath())
+                    .isEqualTo("/data/user/" + userId + "/com.android.microdroid.test/vm/vm-name");
+        } finally {
+            vmm.delete("vm-name");
+        }
+    }
+
+    @Test
+    @CddTest(requirements = {"9.17/C-1-1"})
+    public void differentManagersForDifferentContexts() throws Exception {
+        final Context ceCtx = getContext().createCredentialProtectedStorageContext();
+        final Context deCtx = getContext().createDeviceProtectedStorageContext();
+        assertThat(ceCtx.getSystemService(VirtualMachineManager.class))
+                .isNotSameInstanceAs(deCtx.getSystemService(VirtualMachineManager.class));
+    }
+
+    @Test
     @CddTest(requirements = {
             "9.17/C-1-1",
             "9.17/C-1-2",
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
index 416eb7b..0980630 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
@@ -29,7 +29,7 @@
     /** The VM requested to shut down. */
     SHUTDOWN = 3,
     /** crosvm had an error starting the VM. */
-    ERROR = 4,
+    START_FAILED = 4,
     /** The VM requested to reboot, possibly as the result of a kernel panic. */
     REBOOT = 5,
     /** The VM or crosvm crashed. */
diff --git a/virtualizationservice/src/atom.rs b/virtualizationservice/src/atom.rs
index 9c74d1e..a880d60 100644
--- a/virtualizationservice/src/atom.rs
+++ b/virtualizationservice/src/atom.rs
@@ -165,6 +165,7 @@
     uid: i32,
     vm_identifier: &str,
     reason: DeathReason,
+    exit_signal: Option<i32>,
     vm_metric: &VmMetric,
 ) {
     let vm_identifier = vm_identifier.to_owned();
@@ -182,7 +183,7 @@
                 DeathReason::KILLED => vm_exited::DeathReason::Killed,
                 DeathReason::UNKNOWN => vm_exited::DeathReason::Unknown,
                 DeathReason::SHUTDOWN => vm_exited::DeathReason::Shutdown,
-                DeathReason::ERROR => vm_exited::DeathReason::Error,
+                DeathReason::START_FAILED => vm_exited::DeathReason::Error,
                 DeathReason::REBOOT => vm_exited::DeathReason::Reboot,
                 DeathReason::CRASH => vm_exited::DeathReason::Crash,
                 DeathReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH => {
@@ -218,6 +219,7 @@
             guest_time_millis,
             rss_vm_kb: rss.vm,
             rss_crosvm_kb: rss.crosvm,
+            exit_signal: exit_signal.unwrap_or_default(),
         };
         wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
         match vm_exited.stats_write() {
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
index 0fdc293..8ac688d 100644
--- a/virtualizationservice/src/crosvm.rs
+++ b/virtualizationservice/src/crosvm.rs
@@ -34,6 +34,7 @@
 use std::mem;
 use std::num::NonZeroU32;
 use std::os::unix::io::{AsRawFd, RawFd, FromRawFd};
+use std::os::unix::process::ExitStatusExt;
 use std::path::{Path, PathBuf};
 use std::process::{Command, ExitStatus};
 use std::sync::{Arc, Condvar, Mutex};
@@ -62,7 +63,7 @@
 const CROSVM_PLATFORM_VERSION: &str = "1.0.0";
 
 /// The exit status which crosvm returns when it has an error starting a VM.
-const CROSVM_ERROR_STATUS: i32 = 1;
+const CROSVM_START_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.
@@ -365,10 +366,18 @@
         self.handle_ramdump().unwrap_or_else(|e| error!("Error handling ramdump: {}", e));
 
         let death_reason = death_reason(&result, &failure_reason);
+        let exit_signal = exit_signal(&result);
+
         self.callbacks.callback_on_died(self.cid, death_reason);
 
         let vm_metric = self.vm_metric.lock().unwrap();
-        write_vm_exited_stats(self.requester_uid as i32, &self.name, death_reason, &*vm_metric);
+        write_vm_exited_stats(
+            self.requester_uid as i32,
+            &self.name,
+            death_reason,
+            exit_signal,
+            &*vm_metric,
+        );
 
         // Delete temporary files.
         if let Err(e) = remove_dir_all(&self.temporary_directory) {
@@ -637,7 +646,7 @@
         match status.code() {
             None => DeathReason::KILLED,
             Some(0) => DeathReason::SHUTDOWN,
-            Some(CROSVM_ERROR_STATUS) => DeathReason::ERROR,
+            Some(CROSVM_START_ERROR_STATUS) => DeathReason::START_FAILED,
             Some(CROSVM_REBOOT_STATUS) => DeathReason::REBOOT,
             Some(CROSVM_CRASH_STATUS) => DeathReason::CRASH,
             Some(CROSVM_WATCHDOG_REBOOT_STATUS) => DeathReason::WATCHDOG_REBOOT,
@@ -648,6 +657,13 @@
     }
 }
 
+fn exit_signal(result: &Result<ExitStatus, io::Error>) -> Option<i32> {
+    match result {
+        Ok(status) => status.signal(),
+        Err(_) => None,
+    }
+}
+
 /// Starts an instance of `crosvm` to manage a new VM.
 fn run_vm(
     config: CrosvmConfig,
diff --git a/vm_payload/stub/readme.txt b/vm_payload/stub/readme.txt
new file mode 100644
index 0000000..47679b5
--- /dev/null
+++ b/vm_payload/stub/readme.txt
@@ -0,0 +1,17 @@
+The stub.c file here is a checked-in version of a generated code file.
+
+It is not needed when building a payload client in the Android build
+system. The build system will automatically generated it (from
+libvm_payload.map.txt) and then compile it to form the stub version of
+libvm_payload.so. Clients link against the stub, but at runtime they
+will use the real libvm_payload.so provided by Microdroid.
+
+This file is here to support non-Android build systems, to allow a
+suitable stub libvm_payload.so to be built.
+
+To update this file, something like the following should work:
+
+lunch aosp_arm64-eng
+m MicrodroidTestNativeLib
+
+The generated stub file can then be found at out/soong/.intermediates/packages/modules/Virtualization/vm_payload/libvm_payload/android_arm64_armv8-a_shared_current/gen/stub.c
diff --git a/vm_payload/stub/stub.c b/vm_payload/stub/stub.c
new file mode 100644
index 0000000..c610766
--- /dev/null
+++ b/vm_payload/stub/stub.c
@@ -0,0 +1,7 @@
+void AVmPayload_notifyPayloadReady() {}
+void AVmPayload_runVsockRpcServer() {}
+void AVmPayload_getVmInstanceSecret() {}
+void AVmPayload_getDiceAttestationChain() {}
+void AVmPayload_getDiceAttestationCdi() {}
+void AVmPayload_getApkContentsPath() {}
+void AVmPayload_getEncryptedStoragePath() {}
diff --git a/vmbase/example/src/pci.rs b/vmbase/example/src/pci.rs
index e4a4b04..10a67b9 100644
--- a/vmbase/example/src/pci.rs
+++ b/vmbase/example/src/pci.rs
@@ -16,7 +16,7 @@
 
 use aarch64_paging::paging::MemoryRegion;
 use alloc::alloc::{alloc, dealloc, Layout};
-use core::ffi::CStr;
+use core::{ffi::CStr, mem::size_of};
 use libfdt::{Fdt, FdtNode, Reg};
 use log::{debug, info};
 use virtio_drivers::{
@@ -28,7 +28,10 @@
 };
 
 /// The standard sector size of a VirtIO block device, in bytes.
-const SECTOR_SIZE_BYTES: u64 = 512;
+const SECTOR_SIZE_BYTES: usize = 512;
+
+/// The size in sectors of the test block device we expect.
+const EXPECTED_SECTOR_COUNT: usize = 4;
 
 /// Finds an FDT node with compatible=pci-host-cam-generic.
 pub fn pci_node(fdt: &Fdt) -> FdtNode {
@@ -40,6 +43,7 @@
 
 pub fn check_pci(reg: Reg<u64>, allocator: &mut PciMemory32Allocator) {
     let mut pci_root = unsafe { PciRoot::new(reg.addr as *mut u8, Cam::MmioCam) };
+    let mut checked_virtio_device_count = 0;
     for (device_function, info) in pci_root.enumerate_bus(0) {
         let (status, command) = pci_root.get_status_command(device_function);
         info!("Found {} at {}, status {:?} command {:?}", info, device_function, status, command);
@@ -53,15 +57,35 @@
                 transport.device_type(),
                 transport.read_device_features(),
             );
-            instantiate_virtio_driver(transport, virtio_type);
+            if check_virtio_device(transport, virtio_type) {
+                checked_virtio_device_count += 1;
+            }
         }
     }
+
+    assert_eq!(checked_virtio_device_count, 1);
 }
 
-fn instantiate_virtio_driver(transport: impl Transport, device_type: DeviceType) {
+/// Checks the given VirtIO device, if we know how to.
+///
+/// Returns true if the device was checked, or false if it was ignored.
+fn check_virtio_device(transport: impl Transport, device_type: DeviceType) -> bool {
     if device_type == DeviceType::Block {
-        let blk = VirtIOBlk::<HalImpl, _>::new(transport).expect("failed to create blk driver");
-        info!("Found {} KiB block device.", blk.capacity() * SECTOR_SIZE_BYTES / 1024);
+        let mut blk = VirtIOBlk::<HalImpl, _>::new(transport).expect("failed to create blk driver");
+        info!("Found {} KiB block device.", blk.capacity() * SECTOR_SIZE_BYTES as u64 / 1024);
+        assert_eq!(blk.capacity(), EXPECTED_SECTOR_COUNT as u64);
+        let mut data = [0; SECTOR_SIZE_BYTES * EXPECTED_SECTOR_COUNT];
+        for i in 0..EXPECTED_SECTOR_COUNT {
+            blk.read_block(i, &mut data[i * SECTOR_SIZE_BYTES..(i + 1) * SECTOR_SIZE_BYTES])
+                .expect("Failed to read block device.");
+        }
+        for (i, chunk) in data.chunks(size_of::<u32>()).enumerate() {
+            assert_eq!(chunk, &(i as u32).to_le_bytes());
+        }
+        info!("Read expected data from block device.");
+        true
+    } else {
+        false
     }
 }
 
diff --git a/vmbase/example/tests/test.rs b/vmbase/example/tests/test.rs
index 57b68ed..d58c8e6 100644
--- a/vmbase/example/tests/test.rs
+++ b/vmbase/example/tests/test.rs
@@ -16,7 +16,7 @@
 
 use android_system_virtualizationservice::{
     aidl::android::system::virtualizationservice::{
-        VirtualMachineConfig::VirtualMachineConfig,
+        DiskImage::DiskImage, VirtualMachineConfig::VirtualMachineConfig,
         VirtualMachineRawConfig::VirtualMachineRawConfig,
     },
     binder::{ParcelFileDescriptor, ProcessState},
@@ -25,7 +25,7 @@
 use log::info;
 use std::{
     fs::File,
-    io::{self, BufRead, BufReader},
+    io::{self, BufRead, BufReader, Write},
     os::unix::io::FromRawFd,
     panic, thread,
 };
@@ -33,6 +33,7 @@
 
 const VMBASE_EXAMPLE_PATH: &str =
     "/data/local/tmp/vmbase_example.integration_test/arm64/vmbase_example.bin";
+const TEST_DISK_IMAGE_PATH: &str = "/data/local/tmp/vmbase_example.integration_test/test_disk.img";
 
 /// Runs the vmbase_example VM as an unprotected VM via VirtualizationService.
 #[test]
@@ -57,13 +58,28 @@
             .with_context(|| format!("Failed to open VM image {}", VMBASE_EXAMPLE_PATH))?,
     );
 
+    // Make file for test disk image.
+    let mut test_image = File::options()
+        .create(true)
+        .read(true)
+        .write(true)
+        .truncate(true)
+        .open(TEST_DISK_IMAGE_PATH)
+        .with_context(|| format!("Failed to open test disk image {}", TEST_DISK_IMAGE_PATH))?;
+    // Write 4 sectors worth of 4-byte numbers counting up.
+    for i in 0u32..512 {
+        test_image.write_all(&i.to_le_bytes())?;
+    }
+    let test_image = ParcelFileDescriptor::new(test_image);
+    let disk_image = DiskImage { image: Some(test_image), writable: false, partitions: vec![] };
+
     let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
         name: String::from("VmBaseTest"),
         kernel: None,
         initrd: None,
         params: None,
         bootloader: Some(bootloader),
-        disks: vec![],
+        disks: vec![disk_image],
         protectedVm: false,
         memoryMib: 300,
         numCpus: 1,
diff --git a/vmclient/src/death_reason.rs b/vmclient/src/death_reason.rs
index fbf2523..34d89fc 100644
--- a/vmclient/src/death_reason.rs
+++ b/vmclient/src/death_reason.rs
@@ -30,7 +30,7 @@
     /// The VM requested to shut down.
     Shutdown,
     /// crosvm had an error starting the VM.
-    Error,
+    StartFailed,
     /// The VM requested to reboot, possibly as the result of a kernel panic.
     Reboot,
     /// The VM or crosvm crashed.
@@ -66,7 +66,7 @@
             AidlDeathReason::KILLED => Self::Killed,
             AidlDeathReason::UNKNOWN => Self::Unknown,
             AidlDeathReason::SHUTDOWN => Self::Shutdown,
-            AidlDeathReason::ERROR => Self::Error,
+            AidlDeathReason::START_FAILED => Self::StartFailed,
             AidlDeathReason::REBOOT => Self::Reboot,
             AidlDeathReason::CRASH => Self::Crash,
             AidlDeathReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH => Self::PvmFirmwarePublicKeyMismatch,