Pass dt symbol argument for devices to crosvm

For crosvm to amend device tree for assigned devices, vendors provide
information about vm dtbo node.

Bug: 297313212
Test: vm run-microdroid and see crosvm argument
Change-Id: I52bc532361a40a0db6c1b6b0b25cc3ef29886f48
diff --git a/virtualizationmanager/src/crosvm.rs b/virtualizationmanager/src/crosvm.rs
index 77dd76f..d14e2df 100644
--- a/virtualizationmanager/src/crosvm.rs
+++ b/virtualizationmanager/src/crosvm.rs
@@ -115,7 +115,7 @@
     pub platform_version: VersionReq,
     pub detect_hangup: bool,
     pub gdb_port: Option<NonZeroU16>,
-    pub vfio_devices: Vec<PathBuf>,
+    pub vfio_devices: Vec<VfioDevice>,
 }
 
 /// A disk image to pass to crosvm for a VM.
@@ -125,6 +125,12 @@
     pub writable: bool,
 }
 
+#[derive(Clone, Debug)]
+pub struct VfioDevice {
+    pub sysfs_path: PathBuf,
+    pub dtbo_node: String,
+}
+
 /// The lifecycle state which the payload in the VM has reported itself to be in.
 ///
 /// Note that the order of enum variants is significant; only forward transitions are allowed by
@@ -144,7 +150,7 @@
     /// The VM has not yet tried to start.
     NotStarted {
         ///The configuration needed to start the VM, if it has not yet been started.
-        config: CrosvmConfig,
+        config: Box<CrosvmConfig>,
     },
     /// The VM has been started.
     Running {
@@ -171,7 +177,8 @@
 pub struct VmMetric {
     /// Recorded timestamp when the VM is started.
     pub start_timestamp: Option<SystemTime>,
-    /// Update most recent guest_time periodically from /proc/[crosvm pid]/stat while VM is running.
+    /// Update most recent guest_time periodically from /proc/[crosvm pid]/stat while VM is
+    /// running.
     pub cpu_guest_time: Option<i64>,
     /// Update maximum RSS values periodically from /proc/[crosvm pid]/smaps while VM is running.
     pub rss: Option<Rss>,
@@ -184,6 +191,7 @@
     fn start(&mut self, instance: Arc<VmInstance>) -> Result<(), Error> {
         let state = mem::replace(self, VmState::Failed);
         if let VmState::NotStarted { config } = state {
+            let config = *config;
             let detect_hangup = config.detect_hangup;
             let (failure_pipe_read, failure_pipe_write) = create_pipe()?;
             let vfio_devices = config.vfio_devices.clone();
@@ -303,7 +311,7 @@
             .flatten()
             .map_or_else(|| format!("{}", requester_uid), |u| u.name);
         let instance = VmInstance {
-            vm_state: Mutex::new(VmState::NotStarted { config }),
+            vm_state: Mutex::new(VmState::NotStarted { config: Box::new(config) }),
             vm_context,
             cid,
             crosvm_control_socket_path: temporary_directory.join("crosvm.sock"),
@@ -342,7 +350,7 @@
         &self,
         child: Arc<SharedChild>,
         mut failure_pipe_read: File,
-        vfio_devices: Vec<PathBuf>,
+        vfio_devices: Vec<VfioDevice>,
     ) {
         let result = child.wait();
         match &result {
@@ -694,9 +702,9 @@
 const SYSFS_PLATFORM_DEVICES_PATH: &str = "/sys/devices/platform/";
 const VFIO_PLATFORM_DRIVER_PATH: &str = "/sys/bus/platform/drivers/vfio-platform";
 
-fn vfio_argument_for_platform_device(path: &Path) -> Result<String, Error> {
+fn vfio_argument_for_platform_device(device: &VfioDevice) -> Result<String, Error> {
     // Check platform device exists
-    let path = path.canonicalize()?;
+    let path = device.sysfs_path.canonicalize()?;
     if !path.starts_with(SYSFS_PLATFORM_DEVICES_PATH) {
         bail!("{path:?} is not a platform device");
     }
@@ -708,7 +716,7 @@
     }
 
     if let Some(p) = path.to_str() {
-        Ok(format!("--vfio={p},iommu=viommu"))
+        Ok(format!("--vfio={p},iommu=viommu,dt-symbol={0}", device.dtbo_node))
     } else {
         bail!("invalid path {path:?}");
     }