diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 2d09e6e8d3..d3b19529b9 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2326,6 +2326,32 @@ error: } +static char * +qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferAddLit(&buf, "pci-assign"); + virBufferVSprintf(&buf, ",host=%.2x:%.2x.%.1x", + dev->source.subsys.u.pci.bus, + dev->source.subsys.u.pci.slot, + dev->source.subsys.u.pci.function); + virBufferVSprintf(&buf, ",id=%s", dev->info.alias); + if (qemuBuildDeviceAddressStr(&buf, &dev->info) < 0) + goto error; + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + /* This function outputs a -chardev command line option which describes only the * host side of the character device */ static void qemudBuildCommandLineChrDevChardevStr(virDomainChrDefPtr dev, @@ -3576,22 +3602,23 @@ int qemudBuildCommandLine(virConnectPtr conn, /* PCI */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { - if (!(qemuCmdFlags & QEMUD_CMD_FLAG_PCIDEVICE)) { + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + ADD_ARG_LIT("-device"); + if (!(pcidev = qemuBuildPCIHostdevDevStr(hostdev))) + goto error; + } else if (qemuCmdFlags & QEMUD_CMD_FLAG_PCIDEVICE) { + ADD_ARG_LIT("-pcidevice"); + if (virAsprintf(&pcidev, "host=%.2x:%.2x.%.1x", + hostdev->source.subsys.u.pci.bus, + hostdev->source.subsys.u.pci.slot, + hostdev->source.subsys.u.pci.function) < 0) + goto no_memory; + } else { qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, "%s", _("PCI device assignment is not supported by this version of qemu")); goto error; } - ret = virAsprintf(&pcidev, "host=%.2x:%.2x.%.1x", - hostdev->source.subsys.u.pci.bus, - hostdev->source.subsys.u.pci.slot, - hostdev->source.subsys.u.pci.function); - if (ret < 0) { - pcidev = NULL; - goto no_memory; - } - ADD_ARG_LIT("-pcidevice"); - ADD_ARG_LIT(pcidev); - VIR_FREE(pcidev); + ADD_ARG(pcidev); } } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args new file mode 100644 index 0000000000..f1865ee7db --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostpci0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.xml new file mode 100644 index 0000000000..ac5ad47eca --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.xml @@ -0,0 +1,27 @@ + + QEMUGuest2 + c7a5fdbd-edaf-9466-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + +
+ + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 2042e2a758..2a2387ed26 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -301,6 +301,7 @@ mymain(int argc, char **argv) DO_TEST("hostdev-usb-address", 0); DO_TEST("hostdev-usb-address-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("hostdev-pci-address", QEMUD_CMD_FLAG_PCIDEVICE); + DO_TEST("hostdev-pci-address-device", QEMUD_CMD_FLAG_PCIDEVICE|QEMUD_CMD_FLAG_DEVICE); DO_TEST_FULL("restore-v1", QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO, "stdio"); DO_TEST_FULL("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "stdio");