diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index ef21fb925b..30ecb4e615 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1899,6 +1899,38 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
if (qemuDomainAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
goto cleanup;
+ /* Only for *new* domains with pcie-root (and no other
+ * manually specified PCI controllers in the definition): If,
+ * after assigning addresses/reserving slots for all devices,
+ * we see that any extra buses have been auto-added, we
+ * understand that the application has left management of PCI
+ * addresses and controllers up to libvirt. In order to allow
+ * such applications to easily support hotplug, we will do a
+ * "one time" reservation of one extra PCIE|HOTPLUGGABLE
+ * slots, which should cause us to auto-add 1 extra
+ * pcie-root-port. The single slot in this root-port will be
+ * available for hotplug, or may also be used when a device is
+ * added to the config offline.
+ */
+
+ if (max_idx <= 0 &&
+ addrs->nbuses > max_idx + 1 &&
+ qemuDomainMachineHasPCIeRoot(def)) {
+ virDomainDeviceInfo info = {
+ .pciConnectFlags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
+ VIR_PCI_CONNECT_TYPE_PCIE_DEVICE)
+ };
+
+ /* if there isn't an empty pcie-root-port, this will
+ * cause one to be added
+ */
+ if (qemuDomainPCIAddressReserveNextSlot(addrs, &info) < 0)
+ goto cleanup;
+ }
+
+ /* now reflect any controllers auto-added to addrs into the
+ * domain controllers list
+ */
for (i = 1; i < addrs->nbuses; i++) {
virDomainDeviceDef dev;
int contIndex;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-secure.args b/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-secure.args
index c014254141..c5fe72bd56 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-secure.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram-secure.args
@@ -21,6 +21,7 @@ readonly=on \
-boot c \
-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \
+-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \
-device virtio-scsi-pci,id=scsi0,bus=pci.2,addr=0x1 \
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-scsi0-0-0-0 \
-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.args b/tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.args
index e49d7e921f..cc9c35590d 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.args
@@ -18,6 +18,7 @@ QEMU_AUDIO_DRV=none \
-boot c \
-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \
+-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \
-device virtio-scsi-pci,id=scsi0,bus=pci.2,addr=0x1 \
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-scsi0-0-0-0 \
-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args
index 9ac30dd685..9d13466f83 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args
@@ -18,5 +18,6 @@ QEMU_AUDIO_DRV=none \
-boot c \
-device ioh3420,port=0x8,chassis=1,id=pci.1,bus=pcie.0,addr=0x1 \
-device ioh3420,port=0x10,chassis=2,id=pci.2,bus=pcie.0,addr=0x2 \
+-device ioh3420,port=0x18,chassis=3,id=pci.3,bus=pcie.0,addr=0x3 \
-device nec-usb-xhci,id=usb,bus=pci.1,addr=0x0 \
-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x0
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args
index daecf96223..ba26326e17 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args
@@ -29,6 +29,7 @@ QEMU_AUDIO_DRV=none \
-device ioh3420,port=0x60,chassis=11,id=pci.11,bus=pcie.0,addr=0xc \
-device ioh3420,port=0x68,chassis=12,id=pci.12,bus=pcie.0,addr=0xd \
-device ioh3420,port=0x70,chassis=13,id=pci.13,bus=pcie.0,addr=0xe \
+-device ioh3420,port=0x78,chassis=14,id=pci.14,bus=pcie.0,addr=0xf \
-device nec-usb-xhci,id=usb,bus=pci.6,addr=0x0 \
-device virtio-scsi-pci,id=scsi0,bus=pci.5,addr=0x0 \
-device virtio-serial-pci,id=virtio-serial0,bus=pci.4,addr=0x0 \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pm-disable-fallback.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pm-disable-fallback.args
index deae687031..739c918d90 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pm-disable-fallback.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pm-disable-fallback.args
@@ -20,4 +20,5 @@ QEMU_AUDIO_DRV=none \
-boot n \
-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \
+-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \
-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x1
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pm-disable.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pm-disable.args
index 871340f9bf..5ee16b7a19 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pm-disable.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pm-disable.args
@@ -20,4 +20,5 @@ QEMU_AUDIO_DRV=none \
-boot n \
-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \
+-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \
-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x1
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args
index d3217d561a..60af251461 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args
@@ -23,6 +23,7 @@ QEMU_AUDIO_DRV=spice \
-device ioh3420,port=0x20,chassis=3,id=pci.3,bus=pcie.0,addr=0x4 \
-device ioh3420,port=0x28,chassis=4,id=pci.4,bus=pcie.0,addr=0x5 \
-device ioh3420,port=0x30,chassis=5,id=pci.5,bus=pcie.0,addr=0x6 \
+-device ioh3420,port=0x38,chassis=6,id=pci.6,bus=pcie.0,addr=0x7 \
-device nec-usb-xhci,id=usb,bus=pci.2,addr=0x0 \
-device virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 \
-drive file=/var/lib/libvirt/images/basic.qcow2,format=qcow2,if=none,\
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 38bd2904b2..985f45dc4b 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -656,6 +656,7 @@ mymain(void)
DO_TEST("machine-smm-opt",
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_MACHINE_OPT,
QEMU_CAPS_MACHINE_SMM_OPT,
@@ -673,10 +674,12 @@ mymain(void)
DO_TEST("boot-floppy-q35",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI);
DO_TEST("bootindex-floppy-q35",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI, QEMU_CAPS_BOOT_MENU,
QEMU_CAPS_BOOTINDEX);
DO_TEST("boot-multi", QEMU_CAPS_BOOT_MENU);
@@ -723,6 +726,7 @@ mymain(void)
DO_TEST("bios-nvram-secure",
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_MACHINE_OPT,
QEMU_CAPS_MACHINE_SMM_OPT,
@@ -1337,18 +1341,22 @@ mymain(void)
QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG);
DO_TEST("usb-controller-default-q35",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_PCI_OHCI,
QEMU_CAPS_PIIX3_USB_UHCI, QEMU_CAPS_NEC_USB_XHCI);
DO_TEST_FAILURE("usb-controller-default-unavailable-q35",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_PCI_OHCI,
QEMU_CAPS_NEC_USB_XHCI);
DO_TEST("usb-controller-explicit-q35",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_PCI_OHCI,
QEMU_CAPS_PIIX3_USB_UHCI, QEMU_CAPS_NEC_USB_XHCI);
DO_TEST_FAILURE("usb-controller-explicit-unavailable-q35",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_PCI_OHCI,
QEMU_CAPS_PIIX3_USB_UHCI);
DO_TEST("usb-controller-xhci",
@@ -1724,10 +1732,12 @@ mymain(void)
DO_TEST("pcie-root",
QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_DEVICE_PCI_BRIDGE,
- QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE);
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420);
DO_TEST("q35",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
@@ -1742,16 +1752,19 @@ mymain(void)
QEMU_CAPS_DEVICE_IOH3420);
DO_TEST("q35-pm-disable",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4,
QEMU_CAPS_ICH9_DISABLE_S3, QEMU_CAPS_ICH9_DISABLE_S4);
DO_TEST("q35-pm-disable-fallback",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4);
DO_TEST("q35-usb2",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
@@ -1759,6 +1772,7 @@ mymain(void)
DO_TEST("q35-usb2-multi",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
@@ -1766,6 +1780,7 @@ mymain(void)
DO_TEST("q35-usb2-reorder",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
@@ -1928,6 +1943,7 @@ mymain(void)
DO_TEST_PARSE_ERROR("q35-wrong-root",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
@@ -2041,6 +2057,7 @@ mymain(void)
DO_TEST("pcihole64-q35",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
QEMU_CAPS_ICH9_AHCI,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
QEMU_CAPS_DEVICE_QXL,
@@ -2073,13 +2090,15 @@ mymain(void)
QEMU_CAPS_DEVICE_VIRTIO_MMIO,
QEMU_CAPS_DEVICE_VIRTIO_RNG, QEMU_CAPS_OBJECT_RNG_RANDOM,
QEMU_CAPS_OBJECT_GPEX, QEMU_CAPS_DEVICE_PCI_BRIDGE,
- QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE);
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420);
DO_TEST("aarch64-virt-2.6-virtio-pci-default",
QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DTB,
QEMU_CAPS_DEVICE_VIRTIO_MMIO,
QEMU_CAPS_DEVICE_VIRTIO_RNG, QEMU_CAPS_OBJECT_RNG_RANDOM,
QEMU_CAPS_OBJECT_GPEX, QEMU_CAPS_DEVICE_PCI_BRIDGE,
- QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE);
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420);
/* Example of using virtio-pci with no explicit PCI controller
but with manual PCI addresses */
DO_TEST("aarch64-virtio-pci-manual-addresses",
@@ -2087,7 +2106,9 @@ mymain(void)
QEMU_CAPS_DEVICE_VIRTIO_MMIO,
QEMU_CAPS_DEVICE_VIRTIO_RNG, QEMU_CAPS_OBJECT_RNG_RANDOM,
QEMU_CAPS_OBJECT_GPEX, QEMU_CAPS_DEVICE_PCI_BRIDGE,
- QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_VIRTIO_SCSI);
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
+ QEMU_CAPS_VIRTIO_SCSI);
DO_TEST("aarch64-video-virtio-gpu-pci",
QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_OBJECT_GPEX,
QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_IOH3420,
@@ -2346,7 +2367,9 @@ mymain(void)
DO_TEST("acpi-table", NONE);
DO_TEST("intel-iommu", QEMU_CAPS_DEVICE_PCI_BRIDGE,
- QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_DEVICE_INTEL_IOMMU);
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
+ QEMU_CAPS_DEVICE_INTEL_IOMMU);
DO_TEST("intel-iommu-machine", QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_MACHINE_OPT,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_MACHINE_IOMMU);
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml
index 8d7bc9da41..e64b80cd88 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml
@@ -31,6 +31,11 @@