43fe83
From 9e884c4b9c843ad6ca60ac8cc5ece2e17d32f7a9 Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <9e884c4b9c843ad6ca60ac8cc5ece2e17d32f7a9.1377873637.git.jdenemar@redhat.com>
43fe83
From: Laine Stump <laine@laine.org>
43fe83
Date: Tue, 6 Aug 2013 13:23:25 -0600
43fe83
Subject: [PATCH] qemu: properly set/use device alias for pci controllers
43fe83
43fe83
This patch is part of the resolution to:
43fe83
43fe83
   https://bugzilla.redhat.com/show_bug.cgi?id=819968
43fe83
43fe83
We had been setting the device alias in the devinceinfo for pci
43fe83
controllers to "pci%u", but then hardcoding "pci.%u" when creating the
43fe83
device address for other devices using that pci bus. This all worked
43fe83
just fine until we encountered the built-in "pcie.0" bus (the PCIe
43fe83
root complex) in Q35 machines.
43fe83
43fe83
In order to create the correct commandline for this one case, this
43fe83
patch:
43fe83
43fe83
1) sets the alias for PCI controllers correctly, to "pci.%u" (or
43fe83
"pcie.%u" for the pcie-root controller)
43fe83
43fe83
2) eliminates the hardcoded "pci.%u" for pci controllers when
43fe83
generatuing device address strings, and instead uses the controller's
43fe83
alias.
43fe83
43fe83
3) plumbs a pointer to the virDomainDef all the way down to
43fe83
qemuBuildDeviceAddressStr. This was necessary in order to make the
43fe83
aliase of the controller *used by a device* available (previously
43fe83
qemuBuildDeviceAddressStr only had the deviceinfo of the device
43fe83
itself, *not* of the controller it was connecting to). This made for a
43fe83
larger than desired diff, but at least in the future we won't have to
43fe83
do it again, since all the information we could possibly ever need for
43fe83
future enhancements is in the virDomainDef. (right?)
43fe83
43fe83
This should be done for *all* controllers, but for now we just do it
43fe83
in the case of PCI controllers, to reduce the likelyhood of
43fe83
regression.
43fe83
(cherry picked from commit 01b8812765f17d1a2592bcec2708315f136fb611)
43fe83
---
43fe83
 src/qemu/qemu_command.c                            | 164 ++++++++++++++-------
43fe83
 src/qemu/qemu_command.h                            |  28 ++--
43fe83
 src/qemu/qemu_hotplug.c                            |   6 +-
43fe83
 tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args |   2 +-
43fe83
 tests/qemuxml2argvdata/qemuxml2argv-q35.args       |   2 +-
43fe83
 5 files changed, 136 insertions(+), 66 deletions(-)
43fe83
43fe83
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
43fe83
index 3e07360..c7e7826 100644
43fe83
--- a/src/qemu/qemu_command.c
43fe83
+++ b/src/qemu/qemu_command.c
43fe83
@@ -860,10 +860,18 @@ qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller)
43fe83
 {
43fe83
     const char *prefix = virDomainControllerTypeToString(controller->type);
43fe83
 
43fe83
-    if (virAsprintf(&controller->info.alias, "%s%d", prefix,
43fe83
-                    controller->idx) < 0)
43fe83
-        return -1;
43fe83
-    return 0;
43fe83
+    if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
43fe83
+        /* only pcie-root uses a different naming convention
43fe83
+         * ("pcie.0"), because it is hardcoded that way in qemu. All
43fe83
+         * other buses use the consistent "pci.%u".
43fe83
+         */
43fe83
+        if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)
43fe83
+            return virAsprintf(&controller->info.alias, "pcie.%d", controller->idx);
43fe83
+        else
43fe83
+            return virAsprintf(&controller->info.alias, "pci.%d", controller->idx);
43fe83
+    }
43fe83
+
43fe83
+    return virAsprintf(&controller->info.alias, "%s%d", prefix, controller->idx);
43fe83
 }
43fe83
 
43fe83
 static ssize_t
43fe83
@@ -2793,22 +2801,57 @@ qemuUsbId(virBufferPtr buf, int idx)
43fe83
 
43fe83
 static int
43fe83
 qemuBuildDeviceAddressStr(virBufferPtr buf,
43fe83
+                          virDomainDefPtr domainDef,
43fe83
                           virDomainDeviceInfoPtr info,
43fe83
                           virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
+    int ret = -1;
43fe83
+    char *devStr = NULL;
43fe83
+
43fe83
     if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
43fe83
+        const char *contAlias = NULL;
43fe83
+        size_t i;
43fe83
+
43fe83
+        if (!(devStr = qemuDomainPCIAddressAsString(&info->addr.pci)))
43fe83
+            goto cleanup;
43fe83
+        for (i = 0; i < domainDef->ncontrollers; i++) {
43fe83
+            virDomainControllerDefPtr cont = domainDef->controllers[i];
43fe83
+
43fe83
+            if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
43fe83
+                cont->idx == info->addr.pci.bus) {
43fe83
+                contAlias = cont->info.alias;
43fe83
+                if (!contAlias) {
43fe83
+                    virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
+                                   _("Device alias was not set for PCI "
43fe83
+                                     "controller with index %u required "
43fe83
+                                     "for device at address %s"),
43fe83
+                                   info->addr.pci.bus, devStr);
43fe83
+                    goto cleanup;
43fe83
+                }
43fe83
+                break;
43fe83
+            }
43fe83
+        }
43fe83
+        if (!contAlias) {
43fe83
+            virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
+                           _("Could not find PCI "
43fe83
+                             "controller with index %u required "
43fe83
+                             "for device at address %s"),
43fe83
+                           info->addr.pci.bus, devStr);
43fe83
+            goto cleanup;
43fe83
+        }
43fe83
+
43fe83
         if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) {
43fe83
             if (info->addr.pci.function != 0) {
43fe83
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
43fe83
                                _("Only PCI device addresses with function=0 "
43fe83
                                  "are supported with this QEMU binary"));
43fe83
-                return -1;
43fe83
+                goto cleanup;
43fe83
             }
43fe83
             if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_ON) {
43fe83
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
43fe83
                                _("'multifunction=on' is not supported with "
43fe83
                                  "this QEMU binary"));
43fe83
-                return -1;
43fe83
+                goto cleanup;
43fe83
             }
43fe83
         }
43fe83
 
43fe83
@@ -2822,18 +2865,19 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
43fe83
          */
43fe83
         if (info->addr.pci.bus != 0) {
43fe83
             if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) {
43fe83
-                virBufferAsprintf(buf, ",bus=pci.%u", info->addr.pci.bus);
43fe83
+                virBufferAsprintf(buf, ",bus=%s", contAlias);
43fe83
             } else {
43fe83
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
43fe83
                                _("Multiple PCI buses are not supported "
43fe83
                                  "with this QEMU binary"));
43fe83
-                return -1;
43fe83
+                goto cleanup;
43fe83
             }
43fe83
         } else {
43fe83
-            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS))
43fe83
-                virBufferAddLit(buf, ",bus=pci.0");
43fe83
-            else
43fe83
+            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS)) {
43fe83
+                virBufferAsprintf(buf, ",bus=%s", contAlias);
43fe83
+            } else {
43fe83
                 virBufferAddLit(buf, ",bus=pci");
43fe83
+            }
43fe83
         }
43fe83
         if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_ON)
43fe83
             virBufferAddLit(buf, ",multifunction=on");
43fe83
@@ -2857,7 +2901,10 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
43fe83
                               info->addr.ccw.devno);
43fe83
     }
43fe83
 
43fe83
-    return 0;
43fe83
+    ret = 0;
43fe83
+cleanup:
43fe83
+    VIR_FREE(devStr);
43fe83
+    return ret;
43fe83
 }
43fe83
 
43fe83
 static int
43fe83
@@ -4191,13 +4238,13 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
43fe83
                               (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN)
43fe83
                               ? "on" : "off");
43fe83
         }
43fe83
-        if (qemuBuildDeviceAddressStr(&opt, &disk->info, qemuCaps) < 0)
43fe83
+        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
43fe83
             goto error;
43fe83
         break;
43fe83
     case VIR_DOMAIN_DISK_BUS_USB:
43fe83
         virBufferAddLit(&opt, "usb-storage");
43fe83
 
43fe83
-        if (qemuBuildDeviceAddressStr(&opt, &disk->info, qemuCaps) < 0)
43fe83
+        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
43fe83
             goto error;
43fe83
         break;
43fe83
     default:
43fe83
@@ -4321,7 +4368,8 @@ error:
43fe83
 
43fe83
 
43fe83
 char *
43fe83
-qemuBuildFSDevStr(virDomainFSDefPtr fs,
43fe83
+qemuBuildFSDevStr(virDomainDefPtr def,
43fe83
+                  virDomainFSDefPtr fs,
43fe83
                   virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
     virBuffer opt = VIR_BUFFER_INITIALIZER;
43fe83
@@ -4337,7 +4385,7 @@ qemuBuildFSDevStr(virDomainFSDefPtr fs,
43fe83
     virBufferAsprintf(&opt, ",fsdev=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
43fe83
     virBufferAsprintf(&opt, ",mount_tag=%s", fs->dst);
43fe83
 
43fe83
-    if (qemuBuildDeviceAddressStr(&opt, &fs->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&opt, def, &fs->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&opt)) {
43fe83
@@ -4557,7 +4605,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
43fe83
     if (def->queues)
43fe83
         virBufferAsprintf(&buf, ",num_queues=%u", def->queues);
43fe83
 
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &def->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, domainDef, &def->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&buf)) {
43fe83
@@ -4595,7 +4643,8 @@ qemuBuildNicStr(virDomainNetDefPtr net,
43fe83
 
43fe83
 
43fe83
 char *
43fe83
-qemuBuildNicDevStr(virDomainNetDefPtr net,
43fe83
+qemuBuildNicDevStr(virDomainDefPtr def,
43fe83
+                   virDomainNetDefPtr net,
43fe83
                    int vlan,
43fe83
                    int bootindex,
43fe83
                    virQEMUCapsPtr qemuCaps)
43fe83
@@ -4657,7 +4706,7 @@ qemuBuildNicDevStr(virDomainNetDefPtr net,
43fe83
     virBufferAsprintf(&buf, ",id=%s", net->info.alias);
43fe83
     virBufferAsprintf(&buf, ",mac=%s",
43fe83
                       virMacAddrFormat(&net->mac, macaddr));
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &net->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, &net->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
     if (qemuBuildRomStr(&buf, &net->info, qemuCaps) < 0)
43fe83
        goto error;
43fe83
@@ -4812,7 +4861,8 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
43fe83
 
43fe83
 
43fe83
 char *
43fe83
-qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev,
43fe83
+qemuBuildWatchdogDevStr(virDomainDefPtr def,
43fe83
+                        virDomainWatchdogDefPtr dev,
43fe83
                         virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
     virBuffer buf = VIR_BUFFER_INITIALIZER;
43fe83
@@ -4825,7 +4875,7 @@ qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev,
43fe83
     }
43fe83
 
43fe83
     virBufferAsprintf(&buf, "%s,id=%s", model, dev->info.alias);
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&buf)) {
43fe83
@@ -4842,7 +4892,8 @@ error:
43fe83
 
43fe83
 
43fe83
 char *
43fe83
-qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev,
43fe83
+qemuBuildMemballoonDevStr(virDomainDefPtr def,
43fe83
+                          virDomainMemballoonDefPtr dev,
43fe83
                           virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
     virBuffer buf = VIR_BUFFER_INITIALIZER;
43fe83
@@ -4862,7 +4913,7 @@ qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev,
43fe83
     }
43fe83
 
43fe83
     virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&buf)) {
43fe83
@@ -4905,7 +4956,8 @@ error:
43fe83
 }
43fe83
 
43fe83
 char *
43fe83
-qemuBuildUSBInputDevStr(virDomainInputDefPtr dev,
43fe83
+qemuBuildUSBInputDevStr(virDomainDefPtr def,
43fe83
+                        virDomainInputDefPtr dev,
43fe83
                         virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
     virBuffer buf = VIR_BUFFER_INITIALIZER;
43fe83
@@ -4914,7 +4966,7 @@ qemuBuildUSBInputDevStr(virDomainInputDefPtr dev,
43fe83
                       dev->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
43fe83
                       "usb-mouse" : "usb-tablet", dev->info.alias);
43fe83
 
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&buf)) {
43fe83
@@ -4931,7 +4983,8 @@ error:
43fe83
 
43fe83
 
43fe83
 char *
43fe83
-qemuBuildSoundDevStr(virDomainSoundDefPtr sound,
43fe83
+qemuBuildSoundDevStr(virDomainDefPtr def,
43fe83
+                     virDomainSoundDefPtr sound,
43fe83
                      virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
     virBuffer buf = VIR_BUFFER_INITIALIZER;
43fe83
@@ -4952,7 +5005,7 @@ qemuBuildSoundDevStr(virDomainSoundDefPtr sound,
43fe83
         model = "intel-hda";
43fe83
 
43fe83
     virBufferAsprintf(&buf, "%s,id=%s", model, sound->info.alias);
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &sound->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, &sound->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&buf)) {
43fe83
@@ -5012,7 +5065,8 @@ error:
43fe83
 }
43fe83
 
43fe83
 static char *
43fe83
-qemuBuildDeviceVideoStr(virDomainVideoDefPtr video,
43fe83
+qemuBuildDeviceVideoStr(virDomainDefPtr def,
43fe83
+                        virDomainVideoDefPtr video,
43fe83
                         virQEMUCapsPtr qemuCaps,
43fe83
                         bool primary)
43fe83
 {
43fe83
@@ -5066,7 +5120,7 @@ qemuBuildDeviceVideoStr(virDomainVideoDefPtr video,
43fe83
         virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024);
43fe83
     }
43fe83
 
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &video->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&buf)) {
43fe83
@@ -5106,7 +5160,9 @@ qemuOpenPCIConfig(virDomainHostdevDefPtr dev)
43fe83
 }
43fe83
 
43fe83
 char *
43fe83
-qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd,
43fe83
+qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
43fe83
+                          virDomainHostdevDefPtr dev,
43fe83
+                          const char *configfd,
43fe83
                           virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
     virBuffer buf = VIR_BUFFER_INITIALIZER;
43fe83
@@ -5126,7 +5182,7 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd,
43fe83
     virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
43fe83
     if (dev->info->bootIndex)
43fe83
         virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
     if (qemuBuildRomStr(&buf, dev->info, qemuCaps) < 0)
43fe83
        goto error;
43fe83
@@ -5232,7 +5288,7 @@ qemuBuildRedirdevDevStr(virDomainDefPtr def,
43fe83
         virBufferAsprintf(&buf, ",bootindex=%d", dev->info.bootIndex);
43fe83
     }
43fe83
 
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&buf)) {
43fe83
@@ -5248,7 +5304,8 @@ error:
43fe83
 }
43fe83
 
43fe83
 char *
43fe83
-qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
43fe83
+qemuBuildUSBHostdevDevStr(virDomainDefPtr def,
43fe83
+                          virDomainHostdevDefPtr dev,
43fe83
                           virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
     virBuffer buf = VIR_BUFFER_INITIALIZER;
43fe83
@@ -5271,7 +5328,7 @@ qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
43fe83
     if (dev->info->bootIndex)
43fe83
         virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
43fe83
 
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&buf)) {
43fe83
@@ -5288,7 +5345,8 @@ error:
43fe83
 
43fe83
 
43fe83
 char *
43fe83
-qemuBuildHubDevStr(virDomainHubDefPtr dev,
43fe83
+qemuBuildHubDevStr(virDomainDefPtr def,
43fe83
+                   virDomainHubDefPtr dev,
43fe83
                    virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
     virBuffer buf = VIR_BUFFER_INITIALIZER;
43fe83
@@ -5308,7 +5366,7 @@ qemuBuildHubDevStr(virDomainHubDefPtr dev,
43fe83
 
43fe83
     virBufferAddLit(&buf, "usb-hub");
43fe83
     virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
43fe83
         goto error;
43fe83
 
43fe83
     if (virBufferError(&buf)) {
43fe83
@@ -5829,6 +5887,7 @@ cleanup:
43fe83
 
43fe83
 static int
43fe83
 qemuBuildRNGDeviceArgs(virCommandPtr cmd,
43fe83
+                       virDomainDefPtr def,
43fe83
                        virDomainRNGDefPtr dev,
43fe83
                        virQEMUCapsPtr qemuCaps)
43fe83
 {
43fe83
@@ -5858,7 +5917,7 @@ qemuBuildRNGDeviceArgs(virCommandPtr cmd,
43fe83
             virBufferAddLit(&buf, ",period=1000");
43fe83
     }
43fe83
 
43fe83
-    if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
43fe83
+    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
43fe83
         goto cleanup;
43fe83
 
43fe83
     virCommandAddArg(cmd, "-device");
43fe83
@@ -7133,7 +7192,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
43fe83
         virCommandAddArgList(cmd, "-netdev", host, NULL);
43fe83
     }
43fe83
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
43fe83
-        if (!(nic = qemuBuildNicDevStr(net, vlan, bootindex, qemuCaps)))
43fe83
+        if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex, qemuCaps)))
43fe83
             goto cleanup;
43fe83
         virCommandAddArgList(cmd, "-device", nic, NULL);
43fe83
     } else {
43fe83
@@ -7881,7 +7940,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
         char *optstr;
43fe83
 
43fe83
         virCommandAddArg(cmd, "-device");
43fe83
-        if (!(optstr = qemuBuildHubDevStr(hub, qemuCaps)))
43fe83
+        if (!(optstr = qemuBuildHubDevStr(def, hub, qemuCaps)))
43fe83
             goto error;
43fe83
         virCommandAddArg(cmd, optstr);
43fe83
         VIR_FREE(optstr);
43fe83
@@ -8102,7 +8161,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
             VIR_FREE(optstr);
43fe83
 
43fe83
             virCommandAddArg(cmd, "-device");
43fe83
-            if (!(optstr = qemuBuildFSDevStr(fs, qemuCaps)))
43fe83
+            if (!(optstr = qemuBuildFSDevStr(def, fs, qemuCaps)))
43fe83
                 goto error;
43fe83
             virCommandAddArg(cmd, optstr);
43fe83
             VIR_FREE(optstr);
43fe83
@@ -8460,7 +8519,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
             if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
43fe83
                 char *optstr;
43fe83
                 virCommandAddArg(cmd, "-device");
43fe83
-                if (!(optstr = qemuBuildUSBInputDevStr(input, qemuCaps)))
43fe83
+                if (!(optstr = qemuBuildUSBInputDevStr(def, input, qemuCaps)))
43fe83
                     goto error;
43fe83
                 virCommandAddArg(cmd, optstr);
43fe83
                 VIR_FREE(optstr);
43fe83
@@ -8517,7 +8576,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
             for (i = 0; i < def->nvideos; i++) {
43fe83
                 char *str;
43fe83
                 virCommandAddArg(cmd, "-device");
43fe83
-                if (!(str = qemuBuildDeviceVideoStr(def->videos[i], qemuCaps, !i)))
43fe83
+                if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, !i)))
43fe83
                     goto error;
43fe83
 
43fe83
                 virCommandAddArg(cmd, str);
43fe83
@@ -8591,7 +8650,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
 
43fe83
                         virCommandAddArg(cmd, "-device");
43fe83
 
43fe83
-                        if (!(str = qemuBuildDeviceVideoStr(def->videos[i], qemuCaps, false)))
43fe83
+                        if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, false)))
43fe83
                             goto error;
43fe83
 
43fe83
                         virCommandAddArg(cmd, str);
43fe83
@@ -8655,7 +8714,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
                     virCommandAddArgList(cmd, "-soundhw", "pcspk", NULL);
43fe83
                 } else {
43fe83
                     virCommandAddArg(cmd, "-device");
43fe83
-                    if (!(str = qemuBuildSoundDevStr(sound, qemuCaps)))
43fe83
+                    if (!(str = qemuBuildSoundDevStr(def, sound, qemuCaps)))
43fe83
                         goto error;
43fe83
 
43fe83
                     virCommandAddArg(cmd, str);
43fe83
@@ -8731,7 +8790,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
         if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
43fe83
             virCommandAddArg(cmd, "-device");
43fe83
 
43fe83
-            optstr = qemuBuildWatchdogDevStr(watchdog, qemuCaps);
43fe83
+            optstr = qemuBuildWatchdogDevStr(def, watchdog, qemuCaps);
43fe83
             if (!optstr)
43fe83
                 goto error;
43fe83
         } else {
43fe83
@@ -8844,7 +8903,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
 
43fe83
             if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
43fe83
                 virCommandAddArg(cmd, "-device");
43fe83
-                if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, qemuCaps)))
43fe83
+                if (!(devstr = qemuBuildUSBHostdevDevStr(def, hostdev, qemuCaps)))
43fe83
                     goto error;
43fe83
                 virCommandAddArg(cmd, devstr);
43fe83
                 VIR_FREE(devstr);
43fe83
@@ -8892,7 +8951,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
                     }
43fe83
                 }
43fe83
                 virCommandAddArg(cmd, "-device");
43fe83
-                devstr = qemuBuildPCIHostdevDevStr(hostdev, configfd_name, qemuCaps);
43fe83
+                devstr = qemuBuildPCIHostdevDevStr(def, hostdev, configfd_name, qemuCaps);
43fe83
                 VIR_FREE(configfd_name);
43fe83
                 if (!devstr)
43fe83
                     goto error;
43fe83
@@ -9021,7 +9080,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
             char *optstr;
43fe83
             virCommandAddArg(cmd, "-device");
43fe83
 
43fe83
-            optstr = qemuBuildMemballoonDevStr(def->memballoon, qemuCaps);
43fe83
+            optstr = qemuBuildMemballoonDevStr(def, def->memballoon, qemuCaps);
43fe83
             if (!optstr)
43fe83
                 goto error;
43fe83
             virCommandAddArg(cmd, optstr);
43fe83
@@ -9037,7 +9096,7 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
             goto error;
43fe83
 
43fe83
         /* add the device */
43fe83
-        if (qemuBuildRNGDeviceArgs(cmd, def->rng, qemuCaps) < 0)
43fe83
+        if (qemuBuildRNGDeviceArgs(cmd, def, def->rng, qemuCaps) < 0)
43fe83
             goto error;
43fe83
     }
43fe83
 
43fe83
@@ -9115,6 +9174,7 @@ error:
43fe83
  */
43fe83
 static int
43fe83
 qemuBuildSerialChrDeviceStr(char **deviceStr,
43fe83
+                            virDomainDefPtr def,
43fe83
                             virDomainChrDefPtr serial,
43fe83
                             virQEMUCapsPtr qemuCaps,
43fe83
                             virArch arch,
43fe83
@@ -9127,7 +9187,7 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
43fe83
             serial->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
43fe83
             virBufferAsprintf(&cmd, "spapr-vty,chardev=char%s",
43fe83
                               serial->info.alias);
43fe83
-            if (qemuBuildDeviceAddressStr(&cmd, &serial->info, qemuCaps) < 0)
43fe83
+            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
43fe83
                 goto error;
43fe83
         }
43fe83
     } else {
43fe83
@@ -9149,7 +9209,7 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
43fe83
                 goto error;
43fe83
             }
43fe83
 
43fe83
-            if (qemuBuildDeviceAddressStr(&cmd, &serial->info, qemuCaps) < 0)
43fe83
+            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
43fe83
                 goto error;
43fe83
         }
43fe83
     }
43fe83
@@ -9264,7 +9324,7 @@ qemuBuildChrDeviceStr(char **deviceStr,
43fe83
 
43fe83
     switch ((enum virDomainChrDeviceType) chr->deviceType) {
43fe83
     case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
43fe83
-        ret = qemuBuildSerialChrDeviceStr(deviceStr, chr, qemuCaps,
43fe83
+        ret = qemuBuildSerialChrDeviceStr(deviceStr, vmdef, chr, qemuCaps,
43fe83
                                           vmdef->os.arch,
43fe83
                                           vmdef->os.machine);
43fe83
         break;
43fe83
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
43fe83
index e5111d2..5c5c025 100644
43fe83
--- a/src/qemu/qemu_command.h
43fe83
+++ b/src/qemu/qemu_command.h
43fe83
@@ -98,7 +98,8 @@ char * qemuBuildNicStr(virDomainNetDefPtr net,
43fe83
                        int vlan);
43fe83
 
43fe83
 /* Current, best practice */
43fe83
-char * qemuBuildNicDevStr(virDomainNetDefPtr net,
43fe83
+char * qemuBuildNicDevStr(virDomainDefPtr def,
43fe83
+                          virDomainNetDefPtr net,
43fe83
                           int vlan,
43fe83
                           int bootindex,
43fe83
                           virQEMUCapsPtr qemuCaps);
43fe83
@@ -119,7 +120,8 @@ char * qemuBuildDriveDevStr(virDomainDefPtr def,
43fe83
                             virDomainDiskDefPtr disk,
43fe83
                             int bootindex,
43fe83
                             virQEMUCapsPtr qemuCaps);
43fe83
-char * qemuBuildFSDevStr(virDomainFSDefPtr fs,
43fe83
+char * qemuBuildFSDevStr(virDomainDefPtr domainDef,
43fe83
+                         virDomainFSDefPtr fs,
43fe83
                          virQEMUCapsPtr qemuCaps);
43fe83
 /* Current, best practice */
43fe83
 char * qemuBuildControllerDevStr(virDomainDefPtr domainDef,
43fe83
@@ -127,22 +129,27 @@ char * qemuBuildControllerDevStr(virDomainDefPtr domainDef,
43fe83
                                  virQEMUCapsPtr qemuCaps,
43fe83
                                  int *nusbcontroller);
43fe83
 
43fe83
-char * qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev,
43fe83
+char * qemuBuildWatchdogDevStr(virDomainDefPtr domainDef,
43fe83
+                               virDomainWatchdogDefPtr dev,
43fe83
                                virQEMUCapsPtr qemuCaps);
43fe83
 
43fe83
-char * qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev,
43fe83
+char * qemuBuildMemballoonDevStr(virDomainDefPtr domainDef,
43fe83
+                                 virDomainMemballoonDefPtr dev,
43fe83
                                  virQEMUCapsPtr qemuCaps);
43fe83
 
43fe83
-char * qemuBuildUSBInputDevStr(virDomainInputDefPtr dev,
43fe83
+char * qemuBuildUSBInputDevStr(virDomainDefPtr domainDef,
43fe83
+                               virDomainInputDefPtr dev,
43fe83
                                virQEMUCapsPtr qemuCaps);
43fe83
 
43fe83
-char * qemuBuildSoundDevStr(virDomainSoundDefPtr sound,
43fe83
+char * qemuBuildSoundDevStr(virDomainDefPtr domainDef,
43fe83
+                            virDomainSoundDefPtr sound,
43fe83
                             virQEMUCapsPtr qemuCaps);
43fe83
 
43fe83
 /* Legacy, pre device support */
43fe83
 char * qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev);
43fe83
 /* Current, best practice */
43fe83
-char * qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev,
43fe83
+char * qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
43fe83
+                                 virDomainHostdevDefPtr dev,
43fe83
                                  const char *configfd,
43fe83
                                  virQEMUCapsPtr qemuCaps);
43fe83
 
43fe83
@@ -151,7 +158,8 @@ int qemuOpenPCIConfig(virDomainHostdevDefPtr dev);
43fe83
 /* Legacy, pre device support */
43fe83
 char * qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev);
43fe83
 /* Current, best practice */
43fe83
-char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
43fe83
+char * qemuBuildUSBHostdevDevStr(virDomainDefPtr def,
43fe83
+                                 virDomainHostdevDefPtr dev,
43fe83
                                  virQEMUCapsPtr qemuCaps);
43fe83
 
43fe83
 char * qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
43fe83
@@ -162,7 +170,9 @@ char * qemuBuildSCSIHostdevDevStr(virDomainDefPtr def,
43fe83
                                   virDomainHostdevDefPtr dev,
43fe83
                                   virQEMUCapsPtr qemuCaps);
43fe83
 
43fe83
-char * qemuBuildHubDevStr(virDomainHubDefPtr dev, virQEMUCapsPtr qemuCaps);
43fe83
+char * qemuBuildHubDevStr(virDomainDefPtr def,
43fe83
+                          virDomainHubDefPtr dev,
43fe83
+                          virQEMUCapsPtr qemuCaps);
43fe83
 char * qemuBuildRedirdevDevStr(virDomainDefPtr def,
43fe83
                                virDomainRedirdevDefPtr dev,
43fe83
                                virQEMUCapsPtr qemuCaps);
43fe83
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
43fe83
index 032de69..7a6946e 100644
43fe83
--- a/src/qemu/qemu_hotplug.c
43fe83
+++ b/src/qemu/qemu_hotplug.c
43fe83
@@ -859,7 +859,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
43fe83
     }
43fe83
 
43fe83
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
43fe83
-        if (!(nicstr = qemuBuildNicDevStr(net, vlan, 0, priv->qemuCaps)))
43fe83
+        if (!(nicstr = qemuBuildNicDevStr(vm->def, net, vlan, 0, priv->qemuCaps)))
43fe83
             goto try_remove;
43fe83
     } else {
43fe83
         if (!(nicstr = qemuBuildNicStr(net, NULL, vlan)))
43fe83
@@ -1057,7 +1057,7 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
43fe83
             goto error;
43fe83
         }
43fe83
 
43fe83
-        if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev, configfd_name,
43fe83
+        if (!(devstr = qemuBuildPCIHostdevDevStr(vm->def, hostdev, configfd_name,
43fe83
                                                  priv->qemuCaps)))
43fe83
             goto error;
43fe83
 
43fe83
@@ -1302,7 +1302,7 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
43fe83
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
43fe83
         if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
43fe83
             goto cleanup;
43fe83
-        if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, priv->qemuCaps)))
43fe83
+        if (!(devstr = qemuBuildUSBHostdevDevStr(vm->def, hostdev, priv->qemuCaps)))
43fe83
             goto cleanup;
43fe83
     }
43fe83
 
43fe83
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args
43fe83
index cecef7b..84428f9 100644
43fe83
--- a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args
43fe83
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args
43fe83
@@ -1,5 +1,5 @@
43fe83
 LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/libexec/qemu-kvm \
43fe83
 -S -M q35 -m 2048 -smp 2 -nographic -nodefaults \
43fe83
 -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
43fe83
--device i82801b11-bridge,id=pci.1,bus=pci.0,addr=0x2 \
43fe83
+-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x2 \
43fe83
 -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x1
43fe83
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35.args b/tests/qemuxml2argvdata/qemuxml2argv-q35.args
43fe83
index 6c24407..5ff4bc7 100644
43fe83
--- a/tests/qemuxml2argvdata/qemuxml2argv-q35.args
43fe83
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35.args
43fe83
@@ -1,6 +1,6 @@
43fe83
 LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
43fe83
 /usr/libexec/qemu-kvm -S -M q35 -m 2048 -smp 2 -nographic -nodefaults \
43fe83
 -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
43fe83
--device i82801b11-bridge,id=pci.1,bus=pci.0,addr=0x2 \
43fe83
+-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x2 \
43fe83
 -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x1 \
43fe83
 -vga qxl -global qxl.ram_size=67108864 -global qxl.vram_size=18874368
43fe83
-- 
43fe83
1.8.3.2
43fe83