virtualizationservice: Unbind devices on VM exit
When configured to assign VFIO devices to a VM, virtualizationmanager
will bind them to the VFIO driver before starting the VM. This change
rebinds the default driver after VM exit, so the devices can be used by
the host again.
Test: Assign a device to VM, then check `<device_sysfs>/driver` post exit
Bug: 278008519
Change-Id: I48eee0b0dc1bba40a1c0c543d74f47ec4fee6d78
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index 8c2099f..d775555 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -18,7 +18,7 @@
use crate::atom::{
write_vm_booted_stats, write_vm_creation_stats};
use crate::composite::make_composite_image;
-use crate::crosvm::{CrosvmConfig, DiskFile, PayloadState, VfioDevice, VmContext, VmInstance, VmState};
+use crate::crosvm::{CrosvmConfig, DiskFile, PayloadState, VmContext, VmInstance, VmState};
use crate::debug_config::DebugConfig;
use crate::payload::{add_microdroid_payload_images, add_microdroid_system_images, add_microdroid_vendor_image};
use crate::selinux::{getfilecon, SeContext};
@@ -510,14 +510,7 @@
.or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT);
}
}
- let devices = GLOBAL_SERVICE
- .bindDevicesToVfioDriver(&config.devices)?
- .into_iter()
- .map(|x| VfioDevice {
- sysfs_path: PathBuf::from(&x.sysfsPath),
- dtbo_label: x.dtboLabel,
- })
- .collect::<Vec<_>>();
+ let devices = GLOBAL_SERVICE.bindDevicesToVfioDriver(&config.devices)?;
let dtbo_file = File::from(
GLOBAL_SERVICE
.getDtboFile()?
diff --git a/virtualizationmanager/src/crosvm.rs b/virtualizationmanager/src/crosvm.rs
index 2ba0e0e..50a3c40 100644
--- a/virtualizationmanager/src/crosvm.rs
+++ b/virtualizationmanager/src/crosvm.rs
@@ -47,6 +47,7 @@
VirtualMachineAppConfig::DebugLevel::DebugLevel
};
use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::IGlobalVmContext::IGlobalVmContext;
+use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::IBoundDevice::IBoundDevice;
use binder::Strong;
use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
use tombstoned_client::{TombstonedConnection, DebuggerdDumpType};
@@ -127,11 +128,7 @@
pub writable: bool,
}
-#[derive(Clone, Debug)]
-pub struct VfioDevice {
- pub sysfs_path: PathBuf,
- pub dtbo_label: String,
-}
+type VfioDevice = Strong<dyn IBoundDevice>;
/// The lifecycle state which the payload in the VM has reported itself to be in.
///
@@ -412,10 +409,7 @@
error!("Error removing temporary files from {:?}: {}", self.temporary_directory, e);
});
- // TODO(b/278008182): clean up assigned devices.
- for device in vfio_devices.iter() {
- info!("NOT RELEASING {device:?}");
- }
+ drop(vfio_devices); // Cleanup devices.
}
/// Waits until payload is started, or timeout expires. When timeout occurs, kill
@@ -706,7 +700,7 @@
fn vfio_argument_for_platform_device(device: &VfioDevice) -> Result<String, Error> {
// Check platform device exists
- let path = device.sysfs_path.canonicalize()?;
+ let path = Path::new(&device.getSysfsPath()?).canonicalize()?;
if !path.starts_with(SYSFS_PLATFORM_DEVICES_PATH) {
bail!("{path:?} is not a platform device");
}
@@ -718,7 +712,7 @@
}
if let Some(p) = path.to_str() {
- Ok(format!("--vfio={p},iommu=pkvm-iommu,dt-symbol={0}", device.dtbo_label))
+ Ok(format!("--vfio={p},iommu=pkvm-iommu,dt-symbol={0}", device.getDtboLabel()?))
} else {
bail!("invalid path {path:?}");
}