linux: Instantiate VFIO platform device
Extend VFIO command line option to specify full path to VFIO platform
device that is going to be assigned.
BUG=b:185504618
TEST=trogdor64-manatee SDHCI and GENIQUP device passthrough boots/works
Change-Id: Iad6a24124b383fadb9e025dc64f8a90fa8763ff8
Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2961217
Commit-Queue: Micah Morton <mortonm@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
diff --git a/src/crosvm.rs b/src/crosvm.rs
index 3b7cec1..78dbdc6 100644
--- a/src/crosvm.rs
+++ b/src/crosvm.rs
@@ -205,6 +205,7 @@
#[derive(Eq, PartialEq, Clone, Copy)]
pub enum VfioType {
Pci,
+ Platform,
}
impl FromStr for VfioType {
@@ -214,7 +215,8 @@
use VfioType::*;
match s {
"vfio" => Ok(Pci),
- _ => Err("invalid vfio device type, must be 'vfio'"),
+ "vfio-platform" => Ok(Platform),
+ _ => Err("invalid vfio device type, must be 'vfio|vfio-platform'"),
}
}
}
diff --git a/src/linux.rs b/src/linux.rs
index 434383c..c555482 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -48,7 +48,8 @@
use devices::ProtectionType;
use devices::{
self, BusDeviceObj, HostHotPlugKey, IrqChip, IrqEventIndex, KvmKernelIrqChip, PciAddress,
- PciDevice, VcpuRunState, VfioContainer, VfioDevice, VfioPciDevice, VirtioPciDevice,
+ PciDevice, VcpuRunState, VfioContainer, VfioDevice, VfioPciDevice, VfioPlatformDevice,
+ VirtioPciDevice,
};
#[cfg(feature = "usb")]
use devices::{HostBackendDeviceProvider, XhciController};
@@ -1592,6 +1593,28 @@
Ok((vfio_pci_device, simple_jail(cfg, "vfio_device")?))
}
+fn create_vfio_platform_device(
+ cfg: &Config,
+ vm: &impl Vm,
+ _resources: &mut SystemAllocator,
+ control_tubes: &mut Vec<TaggedControlTube>,
+ vfio_path: &Path,
+ _endpoints: &mut BTreeMap<u32, Arc<Mutex<VfioContainer>>>,
+ iommu_enabled: bool,
+) -> DeviceResult<(VfioPlatformDevice, Option<Minijail>)> {
+ let vfio_container = VfioCommonSetup::vfio_get_container(vfio_path, iommu_enabled)
+ .map_err(Error::CreateVfioDevice)?;
+
+ let (vfio_host_tube_mem, vfio_device_tube_mem) = Tube::pair().map_err(Error::CreateTube)?;
+ control_tubes.push(TaggedControlTube::VmMemory(vfio_host_tube_mem));
+
+ let vfio_device = VfioDevice::new(vfio_path, vm, vfio_container, iommu_enabled)
+ .map_err(Error::CreateVfioDevice)?;
+ let vfio_plat_dev = VfioPlatformDevice::new(vfio_device, vfio_device_tube_mem);
+
+ Ok((vfio_plat_dev, simple_jail(cfg, "vfio_platform_device")?))
+}
+
fn create_devices(
cfg: &Config,
vm: &mut impl Vm,
@@ -1674,6 +1697,25 @@
devices.push((vfio_pci_device, jail));
}
+ for vfio_dev in cfg
+ .vfio
+ .iter()
+ .filter(|dev| dev.get_type() == VfioType::Platform)
+ {
+ let vfio_path = &vfio_dev.vfio_path;
+ let (vfio_plat_dev, jail) = create_vfio_platform_device(
+ cfg,
+ vm,
+ resources,
+ control_tubes,
+ vfio_path.as_path(),
+ &mut iommu_attached_endpoints,
+ false, // Virtio IOMMU is not supported yet
+ )?;
+
+ devices.push((Box::new(vfio_plat_dev), jail));
+ }
+
if !iommu_attached_endpoints.is_empty() {
let iommu_dev = create_iommu_device(cfg, phys_max_addr, iommu_attached_endpoints)?;
diff --git a/src/main.rs b/src/main.rs
index c8bf576..d9b08ee 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1782,7 +1782,7 @@
}
cfg.executable_path = Some(Executable::Bios(PathBuf::from(value.unwrap().to_owned())));
}
- "vfio" => {
+ "vfio" | "vfio-platform" => {
let vfio_type = name.parse().unwrap();
let vfio_dev = VfioCommand::new(vfio_type, value.unwrap())?;
cfg.vfio.push(vfio_dev);
@@ -2186,8 +2186,9 @@
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Argument::flag("split-irqchip", "(EXPERIMENTAL) enable split-irqchip support"),
Argument::value("bios", "PATH", "Path to BIOS/firmware ROM"),
- Argument::value("vfio", "PATH[,iommu=on|off]", "Path to sysfs of pass through or mdev device.
+ Argument::value("vfio", "PATH[,iommu=on|off]", "Path to sysfs of PCI pass through or mdev device.
iommu=on|off - indicates whether to enable virtio IOMMU for this device"),
+ Argument::value("vfio-platform", "PATH", "Path to sysfs of platform pass through"),
#[cfg(feature = "video-decoder")]
Argument::flag("video-decoder", "(EXPERIMENTAL) enable virtio-video decoder device"),
#[cfg(feature = "video-encoder")]