From 8ceadcc5a95dfd2b11bcbb538b51c6f7bc7c6a3f Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 6 Oct 2021 16:29:51 +1100 Subject: [PATCH] agent/device: Sanity check guest IOMMU groups Each VFIO device passed into the guest could represent a whole IOMMU group of devices on the host. Since these devices aren't DMA isolated from each other, they must appear as the same IOMMU group in the guest as well. The VMM should enforce that for us, but double check it, since things can't work otherwise. This also means we determine the guest IOMMU group for the VFIO device, which we'll be needing later. Signed-off-by: David Gibson --- src/agent/src/device.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/agent/src/device.rs b/src/agent/src/device.rs index a07ca6c7ca..f8389fc171 100644 --- a/src/agent/src/device.rs +++ b/src/agent/src/device.rs @@ -597,6 +597,7 @@ async fn vfio_device_handler( _: &DevIndex, ) -> Result<()> { let vfio_in_guest = device.field_type != DRIVER_VFIO_GK_TYPE; + let mut group = None; for opt in device.options.iter() { let (_, pcipath) = @@ -606,6 +607,26 @@ async fn vfio_device_handler( let guestdev = wait_for_pci_device(sandbox, &pcipath).await?; if vfio_in_guest { pci_driver_override(SYSFS_BUS_PCI_PATH, guestdev, "vfio-pci")?; + + let devgroup = pci_iommu_group(SYSFS_BUS_PCI_PATH, guestdev)?; + if devgroup.is_none() { + // Devices must have an IOMMU group to be usable via VFIO + return Err(anyhow!("{} has no IOMMU group", guestdev)); + } + + if group.is_some() && group != devgroup { + // If PCI devices associated with the same VFIO device + // (and therefore group) in the host don't end up in + // the same group in the guest, something has gone + // horribly wrong + return Err(anyhow!( + "{} is not in guest IOMMU group {}", + guestdev, + group.unwrap() + )); + } + + group = devgroup; } } Ok(())