[PATCH v2 3/9] qemu: Move <hostdev/> PCI backend setting into qemuDomainPrepareHostdev()

Michal Privoznik mprivozn at redhat.com
Mon Apr 24 10:41:42 UTC 2023


virsh command domxml-to-native failed with below error but start
command succeed for same domain xml.

  "internal error: invalid PCI passthrough type 'default'"

If a <hostdev> PCI backend is not set in the XML, the supported
one is then chosen in qemuHostdevPreparePCIDevicesCheckSupport().
But this function is not called anywhere from
qemuConnectDomainXMLToNative(). But qemuDomainPrepareHostdev()
is. And it is also called from domain startup/hotplug code.
Therefore, move the backend setting to the common path and drop
qemuHostdevPreparePCIDevicesCheckSupport().

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/qemu/qemu_domain.c  | 50 +++++++++++++++++++++++++++++++-
 src/qemu/qemu_hostdev.c | 64 ++---------------------------------------
 src/qemu/qemu_hotplug.c |  2 +-
 3 files changed, 53 insertions(+), 63 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index f462476d2a..58cd3dd710 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11292,6 +11292,53 @@ qemuDomainPrepareHostdevSCSI(virDomainHostdevDef *hostdev,
 }
 
 
+static int
+qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev,
+                            virQEMUCaps *qemuCaps)
+{
+    bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();
+    virDomainHostdevSubsysPCIBackendType *backend = &hostdev->source.subsys.u.pci.backend;
+
+    /* assign defaults for hostdev passthrough */
+    switch (*backend) {
+    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
+        if (supportsPassthroughVFIO) {
+            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
+                *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
+            } else {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("VFIO PCI device assignment is not supported by this version of QEMU"));
+                return -1;
+            }
+        } else {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("host doesn't support passthrough of host PCI devices"));
+            return -1;
+        }
+        break;
+
+    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
+        if (!supportsPassthroughVFIO) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("host doesn't support VFIO PCI passthrough"));
+            return false;
+        }
+        break;
+
+    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("host doesn't support legacy PCI passthrough"));
+        return false;
+
+    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
+    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
+        break;
+    }
+
+    return true;
+}
+
+
 int
 qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
                          qemuDomainObjPrivate *priv)
@@ -11302,8 +11349,9 @@ qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
     switch ((virDomainHostdevSubsysType)hostdev->source.subsys.type) {
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
         return qemuDomainPrepareHostdevSCSI(hostdev, priv);
-    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+        return qemuDomainPrepareHostdevPCI(hostdev, priv->qemuCaps);
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 45cd1066f0..49347019ea 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -153,60 +153,6 @@ qemuHostdevHostSupportsPassthroughVFIO(void)
 }
 
 
-static bool
-qemuHostdevPreparePCIDevicesCheckSupport(virDomainHostdevDef **hostdevs,
-                                         size_t nhostdevs,
-                                         virQEMUCaps *qemuCaps)
-{
-    bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();
-    size_t i;
-
-    /* assign defaults for hostdev passthrough */
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDef *hostdev = hostdevs[i];
-        virDomainHostdevSubsysPCIBackendType *backend = &hostdev->source.subsys.u.pci.backend;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
-            continue;
-
-        switch (*backend) {
-        case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
-            if (supportsPassthroughVFIO &&
-                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
-                *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
-            } else {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("host doesn't support passthrough of "
-                                 "host PCI devices"));
-                return false;
-            }
-
-            break;
-
-        case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
-            if (!supportsPassthroughVFIO) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("host doesn't support VFIO PCI passthrough"));
-                return false;
-            }
-            break;
-
-        case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("host doesn't support legacy PCI passthrough"));
-            return false;
-
-        case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
-        case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
-            break;
-        }
-    }
-
-    return true;
-}
-
 int
 qemuHostdevPrepareOneNVMeDisk(virQEMUDriver *driver,
                               const char *name,
@@ -235,15 +181,11 @@ qemuHostdevPreparePCIDevices(virQEMUDriver *driver,
                              const unsigned char *uuid,
                              virDomainHostdevDef **hostdevs,
                              int nhostdevs,
-                             virQEMUCaps *qemuCaps,
+                             virQEMUCaps *qemuCaps G_GNUC_UNUSED,
                              unsigned int flags)
 {
-    virHostdevManager *hostdev_mgr = driver->hostdevMgr;
-
-    if (!qemuHostdevPreparePCIDevicesCheckSupport(hostdevs, nhostdevs, qemuCaps))
-        return -1;
-
-    return virHostdevPreparePCIDevices(hostdev_mgr, QEMU_DRIVER_NAME,
+    return virHostdevPreparePCIDevices(driver->hostdevMgr,
+                                       QEMU_DRIVER_NAME,
                                        name, uuid, hostdevs,
                                        nhostdevs, flags);
 }
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 64c62ea114..fab8935346 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1478,7 +1478,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
                                      &hostdev, 1, priv->qemuCaps, flags) < 0)
         return -1;
 
-    /* this could have been changed by qemuHostdevPreparePCIDevices */
+    /* this could have been changed by qemuDomainPrepareHostdevPCI() */
     backend = hostdev->source.subsys.u.pci.backend;
 
     switch (backend) {
-- 
2.39.2



More information about the libvir-list mailing list