[libvirt] [PATCH 5/8] qemu: use vfio-pci on commandline when appropriate

Laine Stump laine at laine.org
Thu Apr 25 17:57:55 UTC 2013


The device option for vfio-pci is nearly identical to that for
pci-assign - only the configfd parameter isn't supported (or needed).

Checking for presence of the bootindex parameter is done separately
from constructing the commandline, similar to how it is done for
pci-assign.
---
 src/qemu/qemu_command.c | 48 ++++++++++++++++++++++++++++++++++++++----------
 src/qemu/qemu_hotplug.c | 13 ++++++++++++-
 2 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4f14dff..761291c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4345,14 +4345,19 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd,
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-    virBufferAddLit(&buf, "pci-assign");
+    if (dev->source.subsys.u.pci.backend
+        == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) {
+        virBufferAddLit(&buf, "vfio-pci");
+    } else {
+        virBufferAddLit(&buf, "pci-assign");
+        if (configfd && *configfd)
+            virBufferAsprintf(&buf, ",configfd=%s", configfd);
+    }
     virBufferAsprintf(&buf, ",host=%.2x:%.2x.%.1x",
                       dev->source.subsys.u.pci.addr.bus,
                       dev->source.subsys.u.pci.addr.slot,
                       dev->source.subsys.u.pci.addr.function);
     virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
-    if (configfd && *configfd)
-        virBufferAsprintf(&buf, ",configfd=%s", configfd);
     if (dev->info->bootIndex)
         virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
     if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0)
@@ -7850,12 +7855,23 @@ qemuBuildCommandLine(virConnectPtr conn,
                                  " supported for PCI and USB devices"));
                 goto error;
             } else {
-                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
-                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_BOOTINDEX)) {
-                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                                   _("booting from assigned PCI devices is not"
-                                     " supported with this version of qemu"));
-                    goto error;
+                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+                    if (hostdev->source.subsys.u.pci.backend
+                        == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) {
+                        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_BOOTINDEX)) {
+                            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                           _("booting from PCI devices assigned with VFIO "
+                                             "is not supported with this version of qemu"));
+                            goto error;
+                        }
+                    } else {
+                        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_BOOTINDEX)) {
+                            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                           _("booting from assigned PCI devices is not"
+                                             " supported with this version of qemu"));
+                            goto error;
+                        }
+                    }
                 }
                 if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
                     !virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HOST_BOOTINDEX)) {
@@ -7889,9 +7905,21 @@ qemuBuildCommandLine(virConnectPtr conn,
         /* PCI */
         if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
             hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+
+            if ((hostdev->source.subsys.u.pci.backend
+                 == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
+                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("VFIO PCI device assignment is not supported by "
+                                 "this version of qemu"));
+                goto error;
+            }
+
             if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
                 char *configfd_name = NULL;
-                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
+                if ((hostdev->source.subsys.u.pci.backend
+                     != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
+                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
                     int configfd = qemuOpenPCIConfig(hostdev);
 
                     if (configfd >= 0) {
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f6b2fc8..30c8bda 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -999,13 +999,24 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
                                      &hostdev, 1) < 0)
         return -1;
 
+    if ((hostdev->source.subsys.u.pci.backend
+         == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
+        !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("VFIO PCI device assignment is not supported by "
+                         "this version of qemu"));
+        goto error;
+    }
+
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
         if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
             goto error;
         if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0)
             goto error;
         releaseaddr = true;
-        if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
+        if ((hostdev->source.subsys.u.pci.backend
+             != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
+            virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
             configfd = qemuOpenPCIConfig(hostdev);
             if (configfd >= 0) {
                 if (virAsprintf(&configfd_name, "fd-%s",
-- 
1.7.11.7




More information about the libvir-list mailing list