[PATCH 7/8] Postpone reprobing till all the devices in iommu group are unbound from vfio

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Author: Shivaprasad G Bhat <sbhat@xxxxxxxxxxxxxxxxxx>

The host will crash if a device is bound to host driver when the device
belonging to same iommu group is in use by any of the guests. So,
do the host driver probe only after all the devices in the iommu group
have unbound from the vfio.

The patch fixes
https://bugzilla.redhat.com/show_bug.cgi?id=1272300

Signed-off-by: Shivaprasad G Bhat <sbhat@xxxxxxxxxxxxxxxxxx>
---
 src/util/virpci.c |   50 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 5 deletions(-)

diff --git a/src/util/virpci.c b/src/util/virpci.c
index 6c24a81..425c1a7 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -1128,6 +1128,23 @@ static int virPCIDeviceReprobeHostDriver(virPCIDevicePtr dev, char *driver, char
     return result;
 }
 
+static int virPCIDeviceBoundToVFIODriver(virPCIDeviceAddressPtr devAddr, void *opaque ATTRIBUTE_UNUSED)
+{
+    int ret = 0;
+    virPCIDevicePtr pci = NULL;
+
+    if (!(pci = virPCIDeviceNew(devAddr->domain, devAddr->bus,
+                                devAddr->slot, devAddr->function)))
+        goto cleanup;
+
+    if (STREQ_NULLABLE(pci->stubDriver, "vfio-pci"))
+        ret = -1;
+
+ cleanup:
+    virPCIDeviceFree(pci);
+    return ret;
+}
+
 static int
 virPCIDeviceUnbindFromStub(virPCIDevicePtr dev,
                            virPCIDeviceListPtr activeDevs ATTRIBUTE_UNUSED,
@@ -1177,11 +1194,34 @@ virPCIDeviceUnbindFromStub(virPCIDevicePtr dev,
     dev->remove_slot = false;
 
  reprobe:
-    if (virPCIDeviceReprobeHostDriver(dev, driver, drvdir) < 0)
-        goto cleanup;
-    /* Steal the dev from list inactiveDevs */
-    if (inactiveDevs)
-        virPCIDeviceListDel(inactiveDevs, dev);
+    if (STREQ_NULLABLE(dev->stubDriver, "vfio-pci")) {
+        size_t i = 0;
+        virPCIDeviceAddress devAddr = { dev->domain, dev->bus,
+                                        dev->slot, dev->function };
+        if (virPCIDeviceAddressIOMMUGroupIterate(&devAddr, virPCIDeviceBoundToVFIODriver, NULL) < 0) {
+            result = 0;
+            goto cleanup;
+        }
+
+        while (inactiveDevs && (i < virPCIDeviceListCount(inactiveDevs))) {
+            virPCIDevicePtr pcidev = virPCIDeviceListGet(inactiveDevs, i);
+            if (dev->iommuGroup == pcidev->iommuGroup) {
+                if (virPCIDeviceReprobeHostDriver(pcidev, driver, drvdir) < 0)
+                   goto cleanup;
+                /* Steal the dev from list inactiveDevs */
+                virPCIDeviceListDel(inactiveDevs, pcidev);
+                continue;
+            }
+            i++;
+        }
+    } else {
+        if (virPCIDeviceReprobeHostDriver(dev, driver, drvdir) < 0)
+            goto cleanup;
+        /* Steal the dev from list inactiveDevs */
+
+        if (inactiveDevs)
+            virPCIDeviceListDel(inactiveDevs, dev);
+    }
 
     result = 0;
 

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]