From: Li Zhang <zhlcindy@xxxxxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list