diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 15d2355904..936a43e2f0 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2068,6 +2068,47 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
}
break;
+ case VIR_DOMAIN_CONTROLLER_TYPE_USB:
+ if ((def->controllers[i]->model
+ == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1) &&
+ (def->controllers[i]->info.type
+ == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)) {
+ /* Try to assign the first found USB2 controller to
+ * 00:1D.0 and 2nd to 00:1A.0 (because that is their
+ * standard location on real Q35 hardware) unless they
+ * are already taken, but don't insist on it.
+ *
+ * (NB: all other controllers at the same index will
+ * get assigned to the same slot as the UHCI1 when
+ * addresses are later assigned to all devices.)
+ */
+ bool assign = false;
+
+ memset(&tmp_addr, 0, sizeof(tmp_addr));
+ tmp_addr.slot = 0x1D;
+ if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
+ assign = true;
+ } else {
+ tmp_addr.slot = 0x1A;
+ if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr))
+ assign = true;
+ }
+ if (assign) {
+ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
+ flags, false, true) < 0)
+ goto cleanup;
+ def->controllers[i]->info.type
+ = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+ def->controllers[i]->info.addr.pci.domain = 0;
+ def->controllers[i]->info.addr.pci.bus = 0;
+ def->controllers[i]->info.addr.pci.slot = tmp_addr.slot;
+ def->controllers[i]->info.addr.pci.function = 0;
+ def->controllers[i]->info.addr.pci.multi
+ = VIR_TRISTATE_SWITCH_ON;
+ }
+ }
+ break;
+
case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE &&
def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
@@ -2541,9 +2582,11 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
bool foundAddr = false;
memset(&tmp_addr, 0, sizeof(tmp_addr));
- for (j = 0; j < i; j++) {
+ for (j = 0; j < def->ncontrollers; j++) {
if (IS_USB2_CONTROLLER(def->controllers[j]) &&
- def->controllers[j]->idx == def->controllers[i]->idx) {
+ def->controllers[j]->idx == def->controllers[i]->idx &&
+ def->controllers[j]->info.type
+ == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
addr = def->controllers[j]->info.addr.pci;
foundAddr = true;
break;
@@ -2553,6 +2596,7 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
switch (def->controllers[i]->model) {
case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
addr.function = 7;
+ addr.multi = VIR_TRISTATE_SWITCH_ABSENT;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
addr.function = 0;
@@ -2560,9 +2604,11 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
break;
case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
addr.function = 1;
+ addr.multi = VIR_TRISTATE_SWITCH_ABSENT;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
addr.function = 2;
+ addr.multi = VIR_TRISTATE_SWITCH_ABSENT;
break;
}
@@ -2581,7 +2627,7 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
}
/* Finally we can reserve the slot+function */
if (virDomainPCIAddressReserveAddr(addrs, &addr, flags,
- false, false) < 0)
+ false, foundAddr) < 0)
goto error;
def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-multi.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-multi.args
new file mode 100644
index 0000000000..6ee64fcbe1
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-multi.args
@@ -0,0 +1,40 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/libexec/qemu-kvm \
+-name q35-test \
+-S \
+-M q35 \
+-m 2048 \
+-smp 2 \
+-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi \
+-boot c \
+-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
+-device pci-bridge,chassis_nr=56,id=pci.2,bus=pci.1,addr=0x1 \
+-device ich9-usb-ehci1,id=usb,bus=pcie.0,addr=0x1d.0x7 \
+-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pcie.0,multifunction=on,\
+addr=0x1d \
+-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pcie.0,addr=0x1d.0x1 \
+-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pcie.0,addr=0x1d.0x2 \
+-device ich9-usb-ehci1,id=usb1,bus=pcie.0,addr=0x1a.0x7 \
+-device ich9-usb-uhci1,masterbus=usb1.0,firstport=0,bus=pcie.0,multifunction=on,\
+addr=0x1a \
+-device ich9-usb-uhci2,masterbus=usb1.0,firstport=2,bus=pcie.0,addr=0x1a.0x1 \
+-device ich9-usb-uhci3,masterbus=usb1.0,firstport=4,bus=pcie.0,addr=0x1a.0x2 \
+-device ich9-usb-ehci1,id=usb2,bus=pci.2,addr=0x1.0x7 \
+-device ich9-usb-uhci1,masterbus=usb2.0,firstport=0,bus=pci.2,multifunction=on,\
+addr=0x1 \
+-device ich9-usb-uhci2,masterbus=usb2.0,firstport=2,bus=pci.2,addr=0x1.0x1 \
+-device ich9-usb-uhci3,masterbus=usb2.0,firstport=4,bus=pci.2,addr=0x1.0x2 \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \
+-device ide-drive,bus=ide.0,drive=drive-sata0-0-0,id=sata0-0-0 \
+-vga qxl \
+-global qxl-vga.ram_size=67108864 \
+-global qxl-vga.vram_size=33554432
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-multi.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-multi.xml
new file mode 100644
index 0000000000..3adb81f96c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-multi.xml
@@ -0,0 +1,47 @@
+
+ q35-test
+ 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-reorder.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-reorder.args
new file mode 100644
index 0000000000..4855dee5d7
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-reorder.args
@@ -0,0 +1,40 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/libexec/qemu-kvm \
+-name q35-test \
+-S \
+-M q35 \
+-m 2048 \
+-smp 2 \
+-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi \
+-boot c \
+-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
+-device pci-bridge,chassis_nr=56,id=pci.2,bus=pci.1,addr=0x1 \
+-device ich9-usb-ehci1,id=usb,bus=pcie.0,addr=0x1d.0x7 \
+-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pcie.0,multifunction=on,\
+addr=0x1d \
+-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pcie.0,addr=0x1d.0x1 \
+-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pcie.0,addr=0x1d.0x2 \
+-device ich9-usb-ehci1,id=usb1,bus=pcie.0,addr=0x1a.0x7 \
+-device ich9-usb-uhci1,masterbus=usb1.0,firstport=0,bus=pcie.0,multifunction=on,\
+addr=0x1a \
+-device ich9-usb-uhci3,masterbus=usb1.0,firstport=4,bus=pcie.0,addr=0x1a.0x2 \
+-device ich9-usb-uhci2,masterbus=usb1.0,firstport=2,bus=pcie.0,addr=0x1a.0x1 \
+-device ich9-usb-ehci1,id=usb2,bus=pci.2,addr=0x1.0x7 \
+-device ich9-usb-uhci3,masterbus=usb2.0,firstport=4,bus=pci.2,addr=0x1.0x2 \
+-device ich9-usb-uhci2,masterbus=usb2.0,firstport=2,bus=pci.2,addr=0x1.0x1 \
+-device ich9-usb-uhci1,masterbus=usb2.0,firstport=0,bus=pci.2,multifunction=on,\
+addr=0x1 \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \
+-device ide-drive,bus=ide.0,drive=drive-sata0-0-0,id=sata0-0-0 \
+-vga qxl \
+-global qxl-vga.ram_size=67108864 \
+-global qxl-vga.vram_size=33554432
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-reorder.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-reorder.xml
new file mode 100644
index 0000000000..f7efdc2a44
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2-reorder.xml
@@ -0,0 +1,47 @@
+
+ q35-test
+ 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2.args
new file mode 100644
index 0000000000..4867eac040
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2.args
@@ -0,0 +1,30 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/libexec/qemu-kvm \
+-name q35-test \
+-S \
+-M q35 \
+-m 2048 \
+-smp 2 \
+-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi \
+-boot c \
+-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
+-device pci-bridge,chassis_nr=56,id=pci.2,bus=pci.1,addr=0x1 \
+-device ich9-usb-ehci1,id=usb,bus=pcie.0,addr=0x1d.0x7 \
+-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pcie.0,multifunction=on,\
+addr=0x1d \
+-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pcie.0,addr=0x1d.0x1 \
+-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pcie.0,addr=0x1d.0x2 \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \
+-device ide-drive,bus=ide.0,drive=drive-sata0-0-0,id=sata0-0-0 \
+-vga qxl \
+-global qxl-vga.ram_size=67108864 \
+-global qxl-vga.vram_size=33554432
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2.xml
new file mode 100644
index 0000000000..001aeceb88
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-usb2.xml
@@ -0,0 +1,39 @@
+
+ q35-test
+ 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 0a1eaff377..f746b1b2c6 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1515,6 +1515,27 @@ mymain(void)
QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE,
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, QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_ICH9_AHCI,
+ QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
+ QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
+ QEMU_CAPS_VGA_QXL, QEMU_CAPS_DEVICE_QXL);
+ DO_TEST("q35-usb2-multi",
+ QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_ICH9_AHCI,
+ QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
+ QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
+ QEMU_CAPS_VGA_QXL, QEMU_CAPS_DEVICE_QXL);
+ DO_TEST("q35-usb2-reorder",
+ QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_ICH9_AHCI,
+ QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
+ QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
+ QEMU_CAPS_VGA_QXL, QEMU_CAPS_DEVICE_QXL);
DO_TEST("pcie-root-port",
QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-usb2-multi.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-usb2-multi.xml
new file mode 100644
index 0000000000..5f62468755
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-usb2-multi.xml
@@ -0,0 +1,66 @@
+
+ q35-test
+ 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-usb2-reorder.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-usb2-reorder.xml
new file mode 100644
index 0000000000..1791b7ac13
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-usb2-reorder.xml
@@ -0,0 +1,66 @@
+
+ q35-test
+ 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-usb2.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-usb2.xml
new file mode 100644
index 0000000000..2dfd9d5569
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-usb2.xml
@@ -0,0 +1,46 @@
+
+ q35-test
+ 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index ab20fca296..93d9e59c07 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -518,6 +518,9 @@ mymain(void)
DO_TEST_DIFFERENT("pci-autoadd-idx");
DO_TEST_DIFFERENT("pcie-root");
DO_TEST_DIFFERENT("q35");
+ DO_TEST_DIFFERENT("q35-usb2");
+ DO_TEST_DIFFERENT("q35-usb2-multi");
+ DO_TEST_DIFFERENT("q35-usb2-reorder");
DO_TEST("pcie-root-port");
DO_TEST("pcie-root-port-too-many");
DO_TEST("pcie-switch-upstream-port");