From: Laine Stump Date: Wed, 21 Oct 2015 19:08:49 +0000 (-0400) Subject: qemu: prefer 00:1D.x and 00:1A.x for USB2 controllers on Q35 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=163338ec28857a5c61b38be5b3bf6c52c8b63877;p=libvirt.git qemu: prefer 00:1D.x and 00:1A.x for USB2 controllers on Q35 The real Q35 machine puts the first USB controller set (EHCI+(UHCIx4)) on bus 0 slot 0x1D, and the 2nd USB controller set on bus 0 slot 0x1A, so let's attempt to make the virtual machine match that for controllers with auto-assigned addresses when possible. Three test cases were added to assure that the proper addresses are assigned - one with a single set of unaddressed USB controllers, one with 3 (to grab both preferred slots plus one more), and one with the order of the controller definitions reordered, to assure that the auto-assignment isn't mixed up by order. --- 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");