[libvirt] [PATCH 2/2] qemu: parse vfio command line on PPC platform

Li Zhang zhlcindy at gmail.com
Mon Sep 16 07:42:03 UTC 2013


From: Li Zhang <zhlcindy at linux.vnet.ibm.com>

PPC supports VFIO by assigning iommu groups to guests manually. It needs
the QEMU command line to support it. The command line is as the following:

  -device spapr-pci-vfio-host-bridge,iommu=1,id=SOMEBUS,index=123

This patch will get the iommu group by XML configuration, and all these
devices in the iommu group need to be detached manually before the guest
is created.

Signed-off-by: Li Zhang <zhlcindy at linux.vnet.ibm.com>
---
 src/qemu/qemu_command.c | 55 ++++++++++++++++++++++++++++++++++++++++++-------
 src/qemu/qemu_command.h |  3 +++
 2 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1521431..64f6ba0 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5368,6 +5368,35 @@ qemuOpenPCIConfig(virDomainHostdevDefPtr dev)
 }
 
 char *
+qemuBuildSPAPRVFIODevStr(virDomainHostdevDefPtr dev,
+                         virQEMUCapsPtr qemuCaps)
+{
+    int iommuGroup;
+    virPCIDeviceAddressPtr addr;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    addr = (virPCIDeviceAddressPtr)&dev->source.subsys.u.pci.addr;
+    if ((iommuGroup = virPCIDeviceAddressGetIOMMUGroupNum(addr)) < 0)
+        goto cleanup;
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPAPR_VFIO_BRIDGE)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("SPAPR_VFIO_BRIDGE is not supported by QEMU"));
+        goto cleanup;
+    }
+
+    virBufferAddLit(&buf, "spapr-pci-vfio-host-bridge");
+    virBufferAsprintf(&buf, ",iommu=%d", iommuGroup);
+    virBufferAsprintf(&buf, ",id=VFIOBUS%d", iommuGroup);
+    virBufferAsprintf(&buf, ",index=%d", iommuGroup + 1);
+
+    return virBufferContentAndReset(&buf);
+
+cleanup:
+    virBufferFreeAndReset(&buf);
+    return NULL;
+}
+
+char *
 qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
                           virDomainHostdevDefPtr dev,
                           const char *configfd,
@@ -9221,13 +9250,25 @@ qemuBuildCommandLine(virConnectPtr conn,
                                          VIR_COMMAND_PASS_FD_CLOSE_PARENT);
                     }
                 }
-                virCommandAddArg(cmd, "-device");
-                devstr = qemuBuildPCIHostdevDevStr(def, hostdev, configfd_name, qemuCaps);
-                VIR_FREE(configfd_name);
-                if (!devstr)
-                    goto error;
-                virCommandAddArg(cmd, devstr);
-                VIR_FREE(devstr);
+                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPAPR_VFIO_BRIDGE) &&
+                    hostdev->source.subsys.u.pci.backend ==
+                    VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
+                    def->os.arch == VIR_ARCH_PPC64) {
+                    virCommandAddArg(cmd, "-device");
+                    devstr = qemuBuildSPAPRVFIODevStr(hostdev, qemuCaps);
+                    if (!devstr)
+                        goto error;
+                    virCommandAddArg(cmd, devstr);
+                    VIR_FREE(devstr);
+                } else {
+                    virCommandAddArg(cmd, "-device");
+                    devstr = qemuBuildPCIHostdevDevStr(def, hostdev, configfd_name, qemuCaps);
+                    VIR_FREE(configfd_name);
+                    if (!devstr)
+                        goto error;
+                    virCommandAddArg(cmd, devstr);
+                    VIR_FREE(devstr);
+               }
             } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE)) {
                 virCommandAddArg(cmd, "-pcidevice");
                 if (!(devstr = qemuBuildPCIHostdevPCIDevStr(hostdev)))
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 2f248eb..c764788 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -153,6 +153,9 @@ char * qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
                                  virDomainHostdevDefPtr dev,
                                  const char *configfd,
                                  virQEMUCapsPtr qemuCaps);
+char *
+qemuBuildSPAPRVFIODevStr(virDomainHostdevDefPtr dev,
+                         virQEMUCapsPtr qemuCaps);
 
 int qemuOpenPCIConfig(virDomainHostdevDefPtr dev);
 
-- 
1.8.1.4




More information about the libvir-list mailing list