virtmgr: Pass VM DTBO path to crosvm if devices assigned
crosvm needs to know the path of VM DTBO to be able to populate the
guest device tree. Add a new method on the global VirtualizationService
which creates the file in a temporary directory common to all VMs and
has the file populated by VfioHandler.
Client virtmgr instances can then request a read-only FD for the file
from VirtualizationService. They then pass it as a preserved FD to
crosvm.
Bug: 297313212
Test: vm run-microdroid and see crosvm argument
Change-Id: I5491b9d084a8e845c1ad82d5cfad45b3374bf495
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index 6ae3bbd..acd182c 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -482,7 +482,7 @@
}
};
- let vfio_devices = if !config.devices.is_empty() {
+ let (vfio_devices, dtbo) = if !config.devices.is_empty() {
let mut set = HashSet::new();
for device in config.devices.iter() {
let path = canonicalize(device)
@@ -493,16 +493,25 @@
.or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT);
}
}
- GLOBAL_SERVICE
+ let devices = GLOBAL_SERVICE
.bindDevicesToVfioDriver(&config.devices)?
.into_iter()
.map(|x| VfioDevice {
sysfs_path: PathBuf::from(&x.sysfsPath),
dtbo_label: x.dtboLabel,
})
- .collect::<Vec<_>>()
+ .collect::<Vec<_>>();
+ let dtbo_file = File::from(
+ GLOBAL_SERVICE
+ .getDtboFile()?
+ .as_ref()
+ .try_clone()
+ .context("Failed to create File from ParcelFileDescriptor")
+ .or_binder_exception(ExceptionCode::BAD_PARCELABLE)?,
+ );
+ (devices, Some(dtbo_file))
} else {
- vec![]
+ (vec![], None)
};
// Actually start the VM.
@@ -529,6 +538,7 @@
detect_hangup: is_app_config,
gdb_port,
vfio_devices,
+ dtbo,
dtbo_vendor,
};
let instance = Arc::new(
diff --git a/virtualizationmanager/src/crosvm.rs b/virtualizationmanager/src/crosvm.rs
index 9a50776..2ba0e0e 100644
--- a/virtualizationmanager/src/crosvm.rs
+++ b/virtualizationmanager/src/crosvm.rs
@@ -116,6 +116,7 @@
pub detect_hangup: bool,
pub gdb_port: Option<NonZeroU16>,
pub vfio_devices: Vec<VfioDevice>,
+ pub dtbo: Option<File>,
pub dtbo_vendor: Option<File>,
}
@@ -723,11 +724,23 @@
}
}
-fn append_platform_devices(command: &mut Command, config: &CrosvmConfig) -> Result<(), Error> {
+fn append_platform_devices(
+ command: &mut Command,
+ preserved_fds: &mut Vec<RawFd>,
+ config: &CrosvmConfig,
+) -> Result<(), Error> {
+ if config.vfio_devices.is_empty() {
+ return Ok(());
+ }
+
+ let Some(dtbo) = &config.dtbo else {
+ bail!("VFIO devices assigned but no DTBO available");
+ };
+ command.arg(format!("--device-tree-overlay={},filter", add_preserved_fd(preserved_fds, dtbo)));
+
for device in &config.vfio_devices {
command.arg(vfio_argument_for_platform_device(device)?);
}
- // TODO(b/291192693): add dtbo to command line when assigned device is not empty.
Ok(())
}
@@ -889,7 +902,7 @@
// TODO(b/285855436): Pass dtbo_vendor after --device-tree-overlay crosvm option is supported.
- append_platform_devices(&mut command, &config)?;
+ append_platform_devices(&mut command, &mut preserved_fds, &config)?;
debug!("Preserving FDs {:?}", preserved_fds);
command.preserved_fds(preserved_fds);