From 731b0f36f13155c47e5e712f261e935c9400d137 Mon Sep 17 00:00:00 2001 From: Laine Stump Date: Thu, 25 Apr 2013 07:58:37 -0400 Subject: [PATCH] qemu: use vfio-pci on commandline when appropriate 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. This patch contains tests to check for proper commandline construction. It also includes tests for parser-formatter-parser roundtrips (xml2xml), because those tests use the same data files, and would have failed had they been included before now. qemu: xml/args tests for VFIO hostdev and These should be squashed in with the patch that adds commandline handling of vfio (they would fail at any earlier time). --- src/qemu/qemu_command.c | 56 ++++++++++++++----- src/qemu/qemu_hotplug.c | 13 ++++- .../qemuxml2argv-hostdev-vfio.args | 5 ++ .../qemuxml2argv-hostdev-vfio.xml | 33 +++++++++++ .../qemuxml2argv-net-hostdev-vfio.args | 6 ++ .../qemuxml2argv-net-hostdev-vfio.xml | 41 ++++++++++++++ tests/qemuxml2argvtest.c | 6 ++ tests/qemuxml2xmltest.c | 2 + 8 files changed, 147 insertions(+), 15 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-vfio.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-vfio.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-hostdev-vfio.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-hostdev-vfio.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 4f14dffa6d..6f6b61b798 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) @@ -7846,22 +7851,33 @@ qemuBuildCommandLine(virConnectPtr conn, (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("booting from assigned devices is only" - " supported for PCI and USB devices")); + _("booting from assigned devices is only " + "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)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("booting from assigned USB devices is not" - " supported with this version of qemu")); + _("booting from assigned USB devices is not " + "supported with this version of qemu")); goto error; } } @@ -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 4127a753e6..f608ec41f8 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", diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-vfio.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-vfio.args new file mode 100644 index 0000000000..e6e42ded89 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-vfio.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \ +unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb -hda \ +/dev/HostVG/QEMUGuest2 -device vfio-pci,host=06:12.5,id=hostdev0,\ +bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-vfio.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-vfio.xml new file mode 100644 index 0000000000..8daa53a8ba --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-vfio.xml @@ -0,0 +1,33 @@ + + QEMUGuest2 + c7a5fdbd-edaf-9466-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + +
+ + + + + + + +
+ + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev-vfio.args b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev-vfio.args new file mode 100644 index 0000000000..da5886ec7f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev-vfio.args @@ -0,0 +1,6 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \ +-M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \ +unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-usb -hda /dev/HostVG/QEMUGuest1 \ +-device vfio-pci,host=03:07.1,id=hostdev0,bus=pci.0,addr=0x3 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev-vfio.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev-vfio.xml new file mode 100644 index 0000000000..90419a435b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev-vfio.xml @@ -0,0 +1,41 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + +
+ + + + + + + + +
+ + + + + + + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 25fa5b702a..7c4d1ce686 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -672,6 +672,9 @@ mymain(void) DO_TEST("net-mcast", NONE); DO_TEST("net-hostdev", QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); + DO_TEST("net-hostdev-vfio", + QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, + QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST("serial-vc", NONE); DO_TEST("serial-pty", NONE); @@ -834,6 +837,9 @@ mymain(void) DO_TEST("hostdev-pci-address", QEMU_CAPS_PCIDEVICE); DO_TEST("hostdev-pci-address-device", QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); + DO_TEST("hostdev-vfio", + QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, + QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST("pci-rom", QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_PCI_ROMBAR); diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 0c50482954..a81cfcf364 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -208,6 +208,7 @@ mymain(void) DO_TEST("net-eth-ifname"); DO_TEST("net-virtio-network-portgroup"); DO_TEST("net-hostdev"); + DO_TEST("net-hostdev-vfio"); DO_TEST("net-openvswitch"); DO_TEST("sound"); DO_TEST("sound-device"); @@ -230,6 +231,7 @@ mymain(void) DO_TEST("hostdev-usb-address"); DO_TEST("hostdev-pci-address"); + DO_TEST("hostdev-vfio"); DO_TEST("pci-rom"); DO_TEST("encrypted-disk"); -- GitLab