[libvirt] [PATCH v2 0/4] Use more PCIe, less legacy PCI slots

Due to its unpopularity, I've removed the "hotpluggable" attribute that was in V1 of this patchset, and also auto-assign *all* devices (except primary video and USB2 for historical reasons) to hotpluggable slots only (rather than assigning devices to the non-hotpluggable pcie-root if libvirt doesn't currently allow hotplugging those devices). So these patches have *NO* new configuration - they are just correcting bad (or at least suboptimal) behavior, and should thus be reasonably uncontroversial :-) The first patch corrects an error in where pci-bridge can be plugged in, which isn't really about using more PCI, but *is* about getting devices plugged into the right kind of slots. (tl;dr - a pci-bridge works when plugged into pcie-root, but people who know about PCI tell me that it's "not proper" to do so, so now we don't unless specifically told to). Patch 2 puts virtio devices into PCIe slots when they support it, patch 3 puts the new e1000e network device (which is a PCIe version of the Intel e1000) into a PCIe slot (as long as the machine has PCIe), and patch 3 does the same for the NEC xhci USB3 controller - all of these devices present as PCie devices when in a PCIe slot, and as PCI devices otherwise, and there is no doubt that preferring PCIe is desirable (legacy PCI controllers only exist on Q35 and other PCIe-capable machinetypes as a crutch to use when you have to use a device that is legacy-PCI-only). One exception that isn't handled in this series is that when a virtio device has --disable-modern=on, it will always be a PCI device. Since Jan's patches to support setting that option aren't in yet, I don't do anything about it. Another caveat - since the auto-adding of PCI controllers will currently only add pci-bridge devices, in order for these patches to be useful, you'll need to manually add a <controller type='pci' model='pcie-root-port'/> for each device. Before pushing these patches, I plan to add another patch that auto-adds pcie-*-port as needed, but wanted to post what I have now to get a head start on reviews (especially since many reviewers will be at KVM Forum next week). Finally, if you want to try out these patches, you'll need to apply them on top of jtomko's patch "Introduce QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY", from the most recent version of his virtio version patches. Laine Stump (4): conf: restrict what type of buses will accept a pci-bridge qemu: assign virtio devices to PCIe slot when appropriate qemu: assign e1000e network devices to PCIe controllers when appropriate qemu: assign nec-xhci (USB3) controller to a PCIe address when appropriate src/conf/domain_addr.c | 29 +++- src/conf/domain_addr.h | 4 +- src/qemu/qemu_domain_address.c | 69 ++++++++-- tests/qemuxml2argvdata/qemuxml2argv-autoindex.args | 10 +- tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 58 ++++++++ tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml | 67 +++++++++ .../qemuxml2argv-q35-virtio-pci.args | 58 ++++++++ .../qemuxml2argv-q35-virtio-pci.xml | 67 +++++++++ .../qemuxml2argv-q35-virtio-pcie.args | 56 ++++++++ tests/qemuxml2argvtest.c | 45 +++++- .../qemuxml2xmlout-autoindex.xml | 10 +- .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 152 +++++++++++++++++++++ .../qemuxml2xmlout-q35-virtio-pci.xml | 152 +++++++++++++++++++++ tests/qemuxml2xmltest.c | 40 ++++++ 14 files changed, 788 insertions(+), 29 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml -- 2.7.4

A pci-bridge has *almost* the same rules as a legacy PCI endpoint device for where it can be automatically connected, and until now both had been considered identical. There is one pairing that is okay when specifically requested by the user (i.e. manual assignment), but we want to avoid it when auto-assigning addresses - plugging a pci-bridge directly into pcie-root (it is cleaner to plug in a dmi-to-pci-bridge, then plug the pci-bridge into that). In order to allow that difference, this patch makes a separate CONNECT_TYPE for pci-bridge, and uses it to restrict auto-assigned addresses for pci-bridges to be only on pci-root, pci-expander-bus, dmi-to-pci-bridge, or on another pci-bridge. NB: As with other discouraged-but-seem-to-work configurations (e.g. plugging a legacy PCI device into a pcie-root-port) if someone *really* wants to, they can still force a pci-bridge to be plugged into pcie-root (by manually specifying its PCI address.) --- src/conf/domain_addr.c | 29 ++++++++++++++++++++++------- src/conf/domain_addr.h | 4 +++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index c533edb..88e44df 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -51,11 +51,14 @@ virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) return 0; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: - /* pci-bridge is treated like a standard - * PCI endpoint device, because it can plug into any - * standard PCI slot (it just can't be hotplugged). + /* pci-bridge is treated like a standard PCI endpoint device + * when its address is manually assigned, but needs special + * treatment when auto-assigning addresses (in that case we + * avoid plugging into anything except pci-root, + * dmi-to-pci-bridge, pci-expander-bus, or another + * pci-bridge). */ - return VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + return VIR_PCI_CONNECT_TYPE_PCI_BRIDGE; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: return VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS; @@ -110,6 +113,12 @@ virDomainPCIAddressFlagsCompatible(virPCIDeviceAddressPtr addr, */ if (devFlags & VIR_PCI_CONNECT_HOTPLUGGABLE) busFlags |= VIR_PCI_CONNECT_HOTPLUGGABLE; + /* if the device is a pci-bridge, allow manually + * assigning to any bus that would also accept a + * standard PCI device. + */ + if (devFlags & VIR_PCI_CONNECT_TYPE_PCI_BRIDGE) + devFlags |= VIR_PCI_CONNECT_TYPE_PCI_DEVICE; } /* If this bus doesn't allow the type of connection (PCI @@ -138,6 +147,8 @@ virDomainPCIAddressFlagsCompatible(virPCIDeviceAddressPtr addr, connectStr = "pci-expander-bus"; } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS) { connectStr = "pcie-expander-bus"; + } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCI_BRIDGE) { + connectStr = "pci-bridge"; } else { /* this should never happen. If it does, there is a * bug in the code that sets the flag bits for devices. @@ -247,19 +258,22 @@ virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus, case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI_DEVICE | + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE | VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS); bus->minSlot = 1; bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST; break; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE | - VIR_PCI_CONNECT_TYPE_PCI_DEVICE); + VIR_PCI_CONNECT_TYPE_PCI_DEVICE | + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE); bus->minSlot = 1; bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST; break; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE | - VIR_PCI_CONNECT_TYPE_PCI_DEVICE); + VIR_PCI_CONNECT_TYPE_PCI_DEVICE | + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE); bus->minSlot = 0; bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST; break; @@ -280,7 +294,8 @@ virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus, case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: /* slots 0 - 31, standard PCI slots, * but *not* hot-pluggable */ - bus->flags = VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + bus->flags = (VIR_PCI_CONNECT_TYPE_PCI_DEVICE | + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE); bus->minSlot = 0; bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST; break; diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 596cd4c..0072a08 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -43,6 +43,7 @@ typedef enum { VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE = 1 << 6, VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS = 1 << 7, VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS = 1 << 8, + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE = 1 << 9, } virDomainPCIConnectFlags; /* a combination of all bits that describe the type of connections @@ -55,7 +56,8 @@ typedef enum { VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT | \ VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE | \ VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS | \ - VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS) + VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS | \ + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE) /* combination of all bits that could be used to connect a normal * endpoint device (i.e. excluding the connection possible between an -- 2.7.4

On Mon, 2016-08-15 at 01:50 -0400, Laine Stump wrote:
A pci-bridge has *almost* the same rules as a legacy PCI endpoint device for where it can be automatically connected, and until now both had been considered identical. There is one pairing that is okay when specifically requested by the user (i.e. manual assignment), but we want to avoid it when auto-assigning addresses - plugging a pci-bridge
s/it // Possibly, I don't know, you're the native speaker ;)
directly into pcie-root (it is cleaner to plug in a dmi-to-pci-bridge, then plug the pci-bridge into that). In order to allow that difference, this patch makes a separate CONNECT_TYPE for pci-bridge, and uses it to restrict auto-assigned addresses for pci-bridges to be only on pci-root, pci-expander-bus, dmi-to-pci-bridge, or on another pci-bridge. NB: As with other discouraged-but-seem-to-work configurations (e.g. plugging a legacy PCI device into a pcie-root-port) if someone *really* wants to, they can still force a pci-bridge to be plugged into pcie-root (by manually specifying its PCI address.) --- src/conf/domain_addr.c | 29 ++++++++++++++++++++++------- src/conf/domain_addr.h | 4 +++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index c533edb..88e44df 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -51,11 +51,14 @@ virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) return 0; case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: - /* pci-bridge is treated like a standard - * PCI endpoint device, because it can plug into any - * standard PCI slot (it just can't be hotplugged). + /* pci-bridge is treated like a standard PCI endpoint device + * when its address is manually assigned, but needs special + * treatment when auto-assigning addresses (in that case we + * avoid plugging into anything except pci-root, + * dmi-to-pci-bridge, pci-expander-bus, or another + * pci-bridge). */ - return VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + return VIR_PCI_CONNECT_TYPE_PCI_BRIDGE;
As mentioned as part of my review of the previous PCIe series, I don't think this kind of comment should be here. The function just maps controller model to connect type, and if anything this change makes the mapping even more straighforward. See below.
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: return VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS; @@ -110,6 +113,12 @@ virDomainPCIAddressFlagsCompatible(virPCIDeviceAddressPtr addr, */ if (devFlags & VIR_PCI_CONNECT_HOTPLUGGABLE) busFlags |= VIR_PCI_CONNECT_HOTPLUGGABLE; + /* if the device is a pci-bridge, allow manually + * assigning to any bus that would also accept a + * standard PCI device. + */ + if (devFlags & VIR_PCI_CONNECT_TYPE_PCI_BRIDGE) + devFlags |= VIR_PCI_CONNECT_TYPE_PCI_DEVICE;
This is the kind of comment we need :) ACK with the nits fixed. -- Andrea Bolognani / Red Hat / Virtualization

On 08/16/2016 10:17 AM, Andrea Bolognani wrote:
On Mon, 2016-08-15 at 01:50 -0400, Laine Stump wrote:
A pci-bridge has *almost* the same rules as a legacy PCI endpoint device for where it can be automatically connected, and until now both had been considered identical. There is one pairing that is okay when specifically requested by the user (i.e. manual assignment), but we want to avoid it when auto-assigning addresses - plugging a pci-bridge s/it //
Possibly, I don't know, you're the native speaker ;)
directly into pcie-root (it is cleaner to plug in a dmi-to-pci-bridge, then plug the pci-bridge into that).
In order to allow that difference, this patch makes a separate CONNECT_TYPE for pci-bridge, and uses it to restrict auto-assigned addresses for pci-bridges to be only on pci-root, pci-expander-bus, dmi-to-pci-bridge, or on another pci-bridge.
NB: As with other discouraged-but-seem-to-work configurations (e.g. plugging a legacy PCI device into a pcie-root-port) if someone *really* wants to, they can still force a pci-bridge to be plugged into pcie-root (by manually specifying its PCI address.) --- src/conf/domain_addr.c | 29 ++++++++++++++++++++++------- src/conf/domain_addr.h | 4 +++- 2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index c533edb..88e44df 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -51,11 +51,14 @@ virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) return 0;
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: - /* pci-bridge is treated like a standard - * PCI endpoint device, because it can plug into any - * standard PCI slot (it just can't be hotplugged). + /* pci-bridge is treated like a standard PCI endpoint device + * when its address is manually assigned, but needs special + * treatment when auto-assigning addresses (in that case we + * avoid plugging into anything except pci-root, + * dmi-to-pci-bridge, pci-expander-bus, or another + * pci-bridge). */ - return VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + return VIR_PCI_CONNECT_TYPE_PCI_BRIDGE; As mentioned as part of my review of the previous PCIe series, I don't think this kind of comment should be here. The function just maps controller model to connect type, and if anything this change makes the mapping even more straighforward.
That's strange. I could *swear* that I removed that comment when I was rebasing. Of course then I created a completely new branch and cherry-picked the commits I wanted using the commit id's from an instance of gitk that was sitting on the desktop - maybe it had been run prior to the deletion and I hadn't reloaded it...
See below.
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: return VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS; @@ -110,6 +113,12 @@ virDomainPCIAddressFlagsCompatible(virPCIDeviceAddressPtr addr, */ if (devFlags & VIR_PCI_CONNECT_HOTPLUGGABLE) busFlags |= VIR_PCI_CONNECT_HOTPLUGGABLE; + /* if the device is a pci-bridge, allow manually + * assigning to any bus that would also accept a + * standard PCI device. + */ + if (devFlags & VIR_PCI_CONNECT_TYPE_PCI_BRIDGE) + devFlags |= VIR_PCI_CONNECT_TYPE_PCI_DEVICE;
This is the kind of comment we need :)
ACK with the nits fixed.
-- Andrea Bolognani / Red Hat / Virtualization

libvirt previously assigned nearly all devices to a hotpluggable legacy PCI slot even on machines with a PCIe root complex. Doing this means that the domain will need a dmi-to-pci-bridge (to convert from PCIe to legacy PCI) and a pci-bridge (to provide hotpluggable legacy PCI slots. To help reduce the need for these legacy controllers, this patch checks for the QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY capability (if that capability is present, then all virtio devices will automatically present as PCIe when attached to a PCIe controller, or PCI when attached to a legacy PCI controller), and assigns virtio devices to a hotpluggable PCIe slot instead. NB: since the slot must be hotpluggable, and pcie-root (the PCIe root complex) does *not* support hotplug, this means that suitable controllers must also be in the config (i.e. either pcie-root-port, or pcie-downstream-port). For now, libvirt doesn't add those automatically, so if you put virtio devices in a config for a qemu that has PCIe-capable virtio devices, you'll need to add extra pcie-root-ports yourself. That requirement will be eliminated in a future patch, but for now, it's simple to do this: <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> ... Partially Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1330024 --- src/qemu/qemu_domain_address.c | 60 +++++++-- tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 57 ++++++++ tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml | 60 +++++++++ .../qemuxml2argv-q35-virtio-pci.args | 57 ++++++++ .../qemuxml2argv-q35-virtio-pci.xml | 60 +++++++++ .../qemuxml2argv-q35-virtio-pcie.args | 56 ++++++++ tests/qemuxml2argvtest.c | 43 +++++- .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 149 +++++++++++++++++++++ .../qemuxml2xmlout-q35-virtio-pci.xml | 149 +++++++++++++++++++++ tests/qemuxml2xmltest.c | 40 ++++++ 10 files changed, 720 insertions(+), 11 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 3d52d72..49181d1 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -997,15 +997,22 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, { size_t i, j; virDomainPCIConnectFlags flags = 0; /* initialize to quiet gcc warning */ + virDomainPCIConnectFlags virtioFlags; + virDomainPCIConnectFlags pciFlags; + virDomainPCIConnectFlags pcieFlags; virPCIDeviceAddress tmp_addr; + bool havePCIeRoot = false; /* PCI controllers */ for (i = 0; i < def->ncontrollers; i++) { if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) { virDomainControllerModelPCI model = def->controllers[i]->model; + if (model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) { + havePCIeRoot = true; + continue; + } if (model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT || - model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT || !virDeviceInfoPCIAddressWanted(&def->controllers[i]->info)) continue; @@ -1021,17 +1028,22 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, } } - /* all other devices that plug into a PCI slot are treated as a - * PCI endpoint devices that require a hotplug-capable slot - * (except for some special cases which have specific handling - * below) + pciFlags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + pcieFlags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCIE_DEVICE; + /* if qemu has the disable-legacy option for + * virtio-net, then its virtio devices will present + * themselves as PCIe devices when plugged into a PCIe + * slot, so we can safely assign them to a PCIe slot. */ - flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + virtioFlags = havePCIeRoot && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY) ? + pcieFlags : pciFlags; for (i = 0; i < def->nfss; i++) { if (!virDeviceInfoPCIAddressWanted(&def->fss[i]->info)) continue; + flags = virtioFlags; /* Only support VirtIO-9p-pci so far. If that changes, * we might need to skip devices here */ if (virDomainPCIAddressReserveNextSlot(addrs, &def->fss[i]->info, @@ -1045,12 +1057,18 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, * in hostdevs list anyway, so handle them with other hostdevs * instead of here. */ - if ((def->nets[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || - !virDeviceInfoPCIAddressWanted(&def->nets[i]->info)) { + virDomainNetDefPtr net = def->nets[i]; + + if ((net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || + !virDeviceInfoPCIAddressWanted(&net->info)) { continue; } - if (virDomainPCIAddressReserveNextSlot(addrs, &def->nets[i]->info, - flags) < 0) + if (STREQ(net->model, "virtio")) + flags = virtioFlags; + else + flags = pciFlags; + + if (virDomainPCIAddressReserveNextSlot(addrs, &net->info, flags) < 0) goto error; } @@ -1064,6 +1082,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_USB) continue; + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->sounds[i]->info, flags) < 0) goto error; @@ -1094,6 +1113,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, if (!virDeviceInfoPCIAddressWanted(&def->controllers[i]->info)) continue; + flags = pciFlags; /* USB2 needs special handling to put all companions in the same slot */ if (IS_USB2_CONTROLLER(def->controllers[i])) { virPCIDeviceAddress addr = { 0, 0, 0, 0, false }; @@ -1150,6 +1170,12 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; def->controllers[i]->info.addr.pci = addr; } else { + if ((def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI && + def->controllers[i]->model == + VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI) || + (def->controllers[i]->type == + VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL)) + flags = virtioFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->controllers[i]->info, flags) < 0) @@ -1184,6 +1210,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, goto error; } + flags = virtioFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->disks[i]->info, flags) < 0) goto error; @@ -1197,6 +1224,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, def->hostdevs[i]->info, flags) < 0) @@ -1207,6 +1235,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, if (def->memballoon && def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO && virDeviceInfoPCIAddressWanted(&def->memballoon->info)) { + flags = virtioFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->memballoon->info, flags) < 0) @@ -1219,6 +1248,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, !virDeviceInfoPCIAddressWanted(&def->rngs[i]->info)) continue; + flags = virtioFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->rngs[i]->info, flags) < 0) goto error; @@ -1228,6 +1258,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, if (def->watchdog && def->watchdog->model == VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB && virDeviceInfoPCIAddressWanted(&def->watchdog->info)) { + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->watchdog->info, flags) < 0) goto error; @@ -1237,6 +1268,10 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, * assigned address. */ if (def->nvideos > 0 && virDeviceInfoPCIAddressWanted(&def->videos[0]->info)) { + if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) + flags = virtioFlags; + else + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[0]->info, flags) < 0) goto error; @@ -1251,6 +1286,8 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, } if (!virDeviceInfoPCIAddressWanted(&def->videos[i]->info)) continue; + + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[i]->info, flags) < 0) goto error; @@ -1261,6 +1298,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, if (!virDeviceInfoPCIAddressWanted(&def->shmems[i]->info)) continue; + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->shmems[i]->info, flags) < 0) goto error; @@ -1270,6 +1308,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, !virDeviceInfoPCIAddressWanted(&def->inputs[i]->info)) continue; + flags = virtioFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->inputs[i]->info, flags) < 0) goto error; @@ -1284,6 +1323,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, !virDeviceInfoPCIAddressWanted(&chr->info)) continue; + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &chr->info, flags) < 0) goto error; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args new file mode 100644 index 0000000..2ea0c08 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args @@ -0,0 +1,57 @@ +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,sockets=2,cores=1,threads=1 \ +-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \ +-no-acpi \ +-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 ioh3420,port=0x18,chassis=4,id=pci.4,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x20,chassis=5,id=pci.5,bus=pcie.0,addr=0x4 \ +-device ioh3420,port=0x28,chassis=6,id=pci.6,bus=pcie.0,addr=0x5 \ +-device ioh3420,port=0x30,chassis=7,id=pci.7,bus=pcie.0,addr=0x6 \ +-device ioh3420,port=0x38,chassis=8,id=pci.8,bus=pcie.0,addr=0x7 \ +-device ioh3420,port=0x40,chassis=9,id=pci.9,bus=pcie.0,addr=0x8 \ +-device ioh3420,port=0x48,chassis=10,id=pci.10,bus=pcie.0,addr=0x9 \ +-device ioh3420,port=0x50,chassis=11,id=pci.11,bus=pcie.0,addr=0xa \ +-device ioh3420,port=0x58,chassis=12,id=pci.12,bus=pcie.0,addr=0xb \ +-device ioh3420,port=0x60,chassis=13,id=pci.13,bus=pcie.0,addr=0xc \ +-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 virtio-scsi-pci,id=scsi0,bus=pci.6,addr=0x0 \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.5,addr=0x0 \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk1 \ +-device virtio-blk-pci,bus=pci.7,addr=0x0,drive=drive-virtio-disk1,\ +id=virtio-disk1 \ +-fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/to/guest \ +-device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=/import/from/host,\ +bus=pci.3,addr=0x0 \ +-netdev user,id=hostnet0 \ +-device virtio-net-pci,netdev=hostnet0,id=net0,mac=00:11:22:33:44:55,bus=pci.4,\ +addr=0x0 \ +-device virtio-input-host-pci,id=input0,evdev=/dev/input/event1234,bus=pci.10,\ +addr=0x0 \ +-device virtio-mouse-pci,id=input1,bus=pci.11,addr=0x0 \ +-device virtio-keyboard-pci,id=input2,bus=pci.12,addr=0x0 \ +-device virtio-tablet-pci,id=input3,bus=pci.13,addr=0x0 \ +-device virtio-vga,id=video0,bus=pcie.0,addr=0x1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.8,addr=0x0 \ +-object rng-random,id=objrng0,filename=/dev/urandom \ +-device virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=123,period=1234,bus=pci.9,\ +addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml new file mode 100644 index 0000000..7bed08c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml @@ -0,0 +1,60 @@ +<domain type='qemu'> + <name>q35-test</name> + <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static' cpuset='0-1'>2</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/libexec/qemu-kvm</emulator> + <controller type='pci' model='pcie-root'/> + <controller type='pci' model='dmi-to-pci-bridge'/> + <controller type='pci' model='pci-bridge'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='virtio-serial'/> + <controller type='scsi' model='virtio-scsi'/> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='vdb' bus='virtio'/> + </disk> + <filesystem type='mount'> + <source dir='/export/to/guest'/> + <target dir='/import/from/host'/> + </filesystem> + <video> + <model type='virtio'/> + </video> + <interface type='user'> + <mac address='00:11:22:33:44:55'/> + <model type='virtio'/> + </interface> + <memballoon model='virtio'/> + <rng model='virtio'> + <rate bytes='123' period='1234'/> + <backend model='random'>/dev/urandom</backend> + </rng> + <input type='passthrough' bus='virtio'> + <source evdev='/dev/input/event1234'/> + </input> + <input type='mouse' bus='virtio'/> + <input type='keyboard' bus='virtio'/> + <input type='tablet' bus='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args new file mode 100644 index 0000000..7cedc82 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args @@ -0,0 +1,57 @@ +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,sockets=2,cores=1,threads=1 \ +-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \ +-no-acpi \ +-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 ioh3420,port=0x18,chassis=4,id=pci.4,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x20,chassis=5,id=pci.5,bus=pcie.0,addr=0x4 \ +-device ioh3420,port=0x28,chassis=6,id=pci.6,bus=pcie.0,addr=0x5 \ +-device ioh3420,port=0x30,chassis=7,id=pci.7,bus=pcie.0,addr=0x6 \ +-device ioh3420,port=0x38,chassis=8,id=pci.8,bus=pcie.0,addr=0x7 \ +-device ioh3420,port=0x40,chassis=9,id=pci.9,bus=pcie.0,addr=0x8 \ +-device ioh3420,port=0x48,chassis=10,id=pci.10,bus=pcie.0,addr=0x9 \ +-device ioh3420,port=0x50,chassis=11,id=pci.11,bus=pcie.0,addr=0xa \ +-device ioh3420,port=0x58,chassis=12,id=pci.12,bus=pcie.0,addr=0xb \ +-device ioh3420,port=0x60,chassis=13,id=pci.13,bus=pcie.0,addr=0xc \ +-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 virtio-scsi-pci,id=scsi0,bus=pci.2,addr=0x4 \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.2,addr=0x3 \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk1 \ +-device virtio-blk-pci,bus=pci.2,addr=0x5,drive=drive-virtio-disk1,\ +id=virtio-disk1 \ +-fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/to/guest \ +-device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=/import/from/host,\ +bus=pci.2,addr=0x1 \ +-netdev user,id=hostnet0 \ +-device virtio-net-pci,netdev=hostnet0,id=net0,mac=00:11:22:33:44:55,bus=pci.2,\ +addr=0x2 \ +-device virtio-input-host-pci,id=input0,evdev=/dev/input/event1234,bus=pci.2,\ +addr=0x8 \ +-device virtio-mouse-pci,id=input1,bus=pci.2,addr=0x9 \ +-device virtio-keyboard-pci,id=input2,bus=pci.2,addr=0xa \ +-device virtio-tablet-pci,id=input3,bus=pci.2,addr=0xb \ +-device virtio-vga,id=video0,bus=pcie.0,addr=0x1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x6 \ +-object rng-random,id=objrng0,filename=/dev/urandom \ +-device virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=123,period=1234,bus=pci.2,\ +addr=0x7 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml new file mode 100644 index 0000000..7bed08c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml @@ -0,0 +1,60 @@ +<domain type='qemu'> + <name>q35-test</name> + <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static' cpuset='0-1'>2</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/libexec/qemu-kvm</emulator> + <controller type='pci' model='pcie-root'/> + <controller type='pci' model='dmi-to-pci-bridge'/> + <controller type='pci' model='pci-bridge'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> + <controller type='virtio-serial'/> + <controller type='scsi' model='virtio-scsi'/> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='vdb' bus='virtio'/> + </disk> + <filesystem type='mount'> + <source dir='/export/to/guest'/> + <target dir='/import/from/host'/> + </filesystem> + <video> + <model type='virtio'/> + </video> + <interface type='user'> + <mac address='00:11:22:33:44:55'/> + <model type='virtio'/> + </interface> + <memballoon model='virtio'/> + <rng model='virtio'> + <rate bytes='123' period='1234'/> + <backend model='random'>/dev/urandom</backend> + </rng> + <input type='passthrough' bus='virtio'> + <source evdev='/dev/input/event1234'/> + </input> + <input type='mouse' bus='virtio'/> + <input type='keyboard' bus='virtio'/> + <input type='tablet' bus='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args new file mode 100644 index 0000000..c43c537 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args @@ -0,0 +1,56 @@ +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,sockets=2,cores=1,threads=1 \ +-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \ +-no-acpi \ +-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 ioh3420,port=0x18,chassis=4,id=pci.4,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x20,chassis=5,id=pci.5,bus=pcie.0,addr=0x4 \ +-device ioh3420,port=0x28,chassis=6,id=pci.6,bus=pcie.0,addr=0x5 \ +-device ioh3420,port=0x30,chassis=7,id=pci.7,bus=pcie.0,addr=0x6 \ +-device ioh3420,port=0x38,chassis=8,id=pci.8,bus=pcie.0,addr=0x7 \ +-device ioh3420,port=0x40,chassis=9,id=pci.9,bus=pcie.0,addr=0x8 \ +-device ioh3420,port=0x48,chassis=10,id=pci.10,bus=pcie.0,addr=0x9 \ +-device ioh3420,port=0x50,chassis=11,id=pci.11,bus=pcie.0,addr=0xa \ +-device ioh3420,port=0x58,chassis=12,id=pci.12,bus=pcie.0,addr=0xb \ +-device ioh3420,port=0x60,chassis=13,id=pci.13,bus=pcie.0,addr=0xc \ +-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 virtio-scsi-pci,id=scsi0,bus=pci.6,addr=0x0 \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.5,addr=0x0 \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk1 \ +-device virtio-blk-pci,bus=pci.7,addr=0x0,drive=drive-virtio-disk1,\ +id=virtio-disk1 \ +-fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/to/guest \ +-device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=/import/from/host,\ +bus=pci.3,addr=0x0 \ +-device virtio-net-pci,vlan=0,id=net0,mac=00:11:22:33:44:55,bus=pci.4,addr=0x0 \ +-net user,vlan=0,name=hostnet0 \ +-device virtio-input-host-pci,id=input0,evdev=/dev/input/event1234,bus=pci.10,\ +addr=0x0 \ +-device virtio-mouse-pci,id=input1,bus=pci.11,addr=0x0 \ +-device virtio-keyboard-pci,id=input2,bus=pci.12,addr=0x0 \ +-device virtio-tablet-pci,id=input3,bus=pci.13,addr=0x0 \ +-device virtio-vga,id=video0,bus=pcie.0,addr=0x1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.8,addr=0x0 \ +-object rng-random,id=objrng0,filename=/dev/urandom \ +-device virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=123,period=1234,bus=pci.9,\ +addr=0x0 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ad0693f..46b602f 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -607,7 +607,6 @@ mymain(void) unsetenv("QEMU_AUDIO_DRV"); unsetenv("SDL_AUDIODRIVER"); - DO_TEST("minimal", NONE); DO_TEST_PARSE_ERROR("minimal-no-memory", NONE); DO_TEST("minimal-msg-timestamp", QEMU_CAPS_MSG_TIMESTAMP); DO_TEST("machine-aliases1", NONE); @@ -1670,6 +1669,48 @@ mymain(void) 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-pcie", + QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM, + QEMU_CAPS_NETDEV, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL, + QEMU_CAPS_VIRTIO_KEYBOARD, + QEMU_CAPS_VIRTIO_MOUSE, + QEMU_CAPS_VIRTIO_TABLET, + QEMU_CAPS_VIRTIO_INPUT_HOST, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_FSDEV, + QEMU_CAPS_FSDEV_WRITEOUT, + 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); + /* same XML as q35-pcie, but don't set QEMU_CAPS_VIRTIO_PCI_LEGACY */ + DO_TEST("q35-virtio-pci", + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM, + QEMU_CAPS_NETDEV, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL, + QEMU_CAPS_VIRTIO_KEYBOARD, + QEMU_CAPS_VIRTIO_MOUSE, + QEMU_CAPS_VIRTIO_TABLET, + QEMU_CAPS_VIRTIO_INPUT_HOST, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_FSDEV, + QEMU_CAPS_FSDEV_WRITEOUT, + 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); DO_TEST("pcie-root-port", QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml new file mode 100644 index 0000000..60e29b5 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml @@ -0,0 +1,149 @@ +<domain type='qemu'> + <name>q35-test</name> + <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static' cpuset='0-1'>2</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/libexec/qemu-kvm</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='vdb' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/> + </disk> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='3' port='0x10'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='4' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='pci' index='5' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='5' port='0x20'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </controller> + <controller type='pci' index='6' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='6' port='0x28'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </controller> + <controller type='pci' index='7' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='7' port='0x30'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </controller> + <controller type='pci' index='8' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='8' port='0x38'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </controller> + <controller type='pci' index='9' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='9' port='0x40'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> + </controller> + <controller type='pci' index='10' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='10' port='0x48'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + </controller> + <controller type='pci' index='11' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='11' port='0x50'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + </controller> + <controller type='pci' index='12' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='12' port='0x58'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + </controller> + <controller type='pci' index='13' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='13' port='0x60'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> + </controller> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> + </controller> + <controller type='scsi' index='0' model='virtio-scsi'> + <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> + </controller> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/> + </controller> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/export/to/guest'/> + <target dir='/import/from/host'/> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> + </filesystem> + <interface type='user'> + <mac address='00:11:22:33:44:55'/> + <model type='virtio'/> + <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> + </interface> + <input type='passthrough' bus='virtio'> + <source evdev='/dev/input/event1234'/> + <address type='pci' domain='0x0000' bus='0x0a' slot='0x00' function='0x0'/> + </input> + <input type='mouse' bus='virtio'> + <address type='pci' domain='0x0000' bus='0x0b' slot='0x00' function='0x0'/> + </input> + <input type='keyboard' bus='virtio'> + <address type='pci' domain='0x0000' bus='0x0c' slot='0x00' function='0x0'/> + </input> + <input type='tablet' bus='virtio'> + <address type='pci' domain='0x0000' bus='0x0d' slot='0x00' function='0x0'/> + </input> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <video> + <model type='virtio' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </video> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/> + </memballoon> + <rng model='virtio'> + <rate bytes='123' period='1234'/> + <backend model='random'>/dev/urandom</backend> + <address type='pci' domain='0x0000' bus='0x09' slot='0x00' function='0x0'/> + </rng> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml new file mode 100644 index 0000000..5c5acac --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml @@ -0,0 +1,149 @@ +<domain type='qemu'> + <name>q35-test</name> + <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <vcpu placement='static' cpuset='0-1'>2</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/libexec/qemu-kvm</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='vdb' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x05' function='0x0'/> + </disk> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='3' port='0x10'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </controller> + <controller type='pci' index='4' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='4' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='pci' index='5' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='5' port='0x20'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </controller> + <controller type='pci' index='6' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='6' port='0x28'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </controller> + <controller type='pci' index='7' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='7' port='0x30'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </controller> + <controller type='pci' index='8' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='8' port='0x38'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </controller> + <controller type='pci' index='9' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='9' port='0x40'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> + </controller> + <controller type='pci' index='10' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='10' port='0x48'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + </controller> + <controller type='pci' index='11' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='11' port='0x50'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + </controller> + <controller type='pci' index='12' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='12' port='0x58'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + </controller> + <controller type='pci' index='13' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='13' port='0x60'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> + </controller> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0'/> + </controller> + <controller type='scsi' index='0' model='virtio-scsi'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x04' function='0x0'/> + </controller> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/> + </controller> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/export/to/guest'/> + <target dir='/import/from/host'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> + </filesystem> + <interface type='user'> + <mac address='00:11:22:33:44:55'/> + <model type='virtio'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x0'/> + </interface> + <input type='passthrough' bus='virtio'> + <source evdev='/dev/input/event1234'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x08' function='0x0'/> + </input> + <input type='mouse' bus='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x09' function='0x0'/> + </input> + <input type='keyboard' bus='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x0a' function='0x0'/> + </input> + <input type='tablet' bus='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x0b' function='0x0'/> + </input> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <video> + <model type='virtio' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </video> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x06' function='0x0'/> + </memballoon> + <rng model='virtio'> + <rate bytes='123' period='1234'/> + <backend model='random'>/dev/urandom</backend> + <address type='pci' domain='0x0000' bus='0x02' slot='0x07' function='0x0'/> + </rng> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 7601a5f..ffd1792 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -691,6 +691,46 @@ mymain(void) 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-pcie", + QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL, + QEMU_CAPS_VIRTIO_KEYBOARD, + QEMU_CAPS_VIRTIO_MOUSE, + QEMU_CAPS_VIRTIO_TABLET, + QEMU_CAPS_VIRTIO_INPUT_HOST, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_FSDEV, + QEMU_CAPS_FSDEV_WRITEOUT, + 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); + /* same XML as q35-pcie, but don't set QEMU_CAPS_VIRTIO_PCI_LEGACY */ + DO_TEST("q35-virtio-pci", + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL, + QEMU_CAPS_VIRTIO_KEYBOARD, + QEMU_CAPS_VIRTIO_MOUSE, + QEMU_CAPS_VIRTIO_TABLET, + QEMU_CAPS_VIRTIO_INPUT_HOST, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_FSDEV, + QEMU_CAPS_FSDEV_WRITEOUT, + 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); DO_TEST("pcie-root", QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, -- 2.7.4

On Mon, 2016-08-15 at 01:50 -0400, Laine Stump wrote:
libvirt previously assigned nearly all devices to a hotpluggable legacy PCI slot even on machines with a PCIe root complex. Doing this means that the domain will need a dmi-to-pci-bridge (to convert from PCIe to legacy PCI) and a pci-bridge (to provide hotpluggable legacy PCI slots. To help reduce the need for these legacy controllers, this patch checks for the QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY capability (if that capability is present, then all virtio devices will automatically present as PCIe when attached to a PCIe controller, or PCI when attached to a legacy PCI controller), and assigns virtio devices to a hotpluggable PCIe slot instead. NB: since the slot must be hotpluggable, and pcie-root (the PCIe root complex) does *not* support hotplug, this means that suitable controllers must also be in the config (i.e. either pcie-root-port, or pcie-downstream-port). For now, libvirt doesn't add those automatically, so if you put virtio devices in a config for a qemu that has PCIe-capable virtio devices, you'll need to add extra pcie-root-ports yourself. That requirement will be eliminated in a future patch, but for now, it's simple to do this: <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> ... Partially Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1330024 ---
[...]
@@ -1021,17 +1028,22 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, } } - /* all other devices that plug into a PCI slot are treated as a - * PCI endpoint devices that require a hotplug-capable slot - * (except for some special cases which have specific handling - * below) + pciFlags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + pcieFlags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCIE_DEVICE;
Blank line here.
+ /* if qemu has the disable-legacy option for + * virtio-net, then its virtio devices will present + * themselves as PCIe devices when plugged into a PCIe + * slot, so we can safely assign them to a PCIe slot. */ - flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + virtioFlags = havePCIeRoot && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY) ? + pcieFlags : pciFlags;
How about unpacking that? I feel like if (havePCIeRoot && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY)) { virtioFlags = pcieFlags; } else { virtioFlags = pciFlags; } would be more readable and maintainable.
for (i = 0; i < def->nfss; i++) { if (!virDeviceInfoPCIAddressWanted(&def->fss[i]->info)) continue; + flags = virtioFlags;
Blank line here.
/* Only support VirtIO-9p-pci so far. If that changes, * we might need to skip devices here */ if (virDomainPCIAddressReserveNextSlot(addrs, &def->fss[i]->info, @@ -1045,12 +1057,18 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, * in hostdevs list anyway, so handle them with other hostdevs * instead of here. */ - if ((def->nets[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || - !virDeviceInfoPCIAddressWanted(&def->nets[i]->info)) { + virDomainNetDefPtr net = def->nets[i]; + + if ((net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || + !virDeviceInfoPCIAddressWanted(&net->info)) { continue; } - if (virDomainPCIAddressReserveNextSlot(addrs, &def->nets[i]->info, - flags) < 0)
Blank line here.
+ if (STREQ(net->model, "virtio")) + flags = virtioFlags; + else + flags = pciFlags;
It's kind of insane that we don't have a virDomainNetModel enum for this sort of check, isn't it?
+ + if (virDomainPCIAddressReserveNextSlot(addrs, &net->info, flags) < 0) goto error; } @@ -1064,6 +1082,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_USB) continue; + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->sounds[i]->info, flags) < 0) goto error; @@ -1094,6 +1113,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, if (!virDeviceInfoPCIAddressWanted(&def->controllers[i]->info)) continue; + flags = pciFlags;
Blank line here.
/* USB2 needs special handling to put all companions in the same slot */ if (IS_USB2_CONTROLLER(def->controllers[i])) { virPCIDeviceAddress addr = { 0, 0, 0, 0, false }; @@ -1150,6 +1170,12 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; def->controllers[i]->info.addr.pci = addr; } else { + if ((def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI && + def->controllers[i]->model == + VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI) || + (def->controllers[i]->type == + VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL)) + flags = virtioFlags;
This is one of those times I really wish our coding style guidelines allowed us to go past 80 columns :) [...]
@@ -1284,6 +1323,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, !virDeviceInfoPCIAddressWanted(&chr->info)) continue; + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &chr->info, flags) < 0) goto error; }
Having gotten this far, I wonder if the pattern used here couldn't be semplified a bit... Try squashing in the attached patch, see if you like it.
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml new file mode 100644 index 0000000..7bed08c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml
As you mention in the test programs below, qemuxml2argv-q35-virtio-pci.xml and qemuxml2argv-q35-pcie.xml have the exact same contents. Please make one of them a symbolic link to the other one, to save space and ensure they will remain in sync.
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args new file mode 100644 index 0000000..c43c537 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args
This looks like a leftover from a previous attempt, and in fact 'make check' still passes after deleting it.
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ad0693f..46b602f 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -607,7 +607,6 @@ mymain(void) unsetenv("QEMU_AUDIO_DRV"); unsetenv("SDL_AUDIODRIVER"); - DO_TEST("minimal", NONE);
No reason to delete this AFAICT.
DO_TEST_PARSE_ERROR("minimal-no-memory", NONE); DO_TEST("minimal-msg-timestamp", QEMU_CAPS_MSG_TIMESTAMP); DO_TEST("machine-aliases1", NONE); @@ -1670,6 +1669,48 @@ mymain(void) 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-pcie", + QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM, + QEMU_CAPS_NETDEV, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL, + QEMU_CAPS_VIRTIO_KEYBOARD, + QEMU_CAPS_VIRTIO_MOUSE, + QEMU_CAPS_VIRTIO_TABLET, + QEMU_CAPS_VIRTIO_INPUT_HOST, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_FSDEV, + QEMU_CAPS_FSDEV_WRITEOUT, + 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); + /* same XML as q35-pcie, but don't set QEMU_CAPS_VIRTIO_PCI_LEGACY */
This is really nice. We have a bunch of tests where the name is not that helpful in conveying exactly what they're supposed to be testing... Actually, adding a few words for q35-pcie would be even nicer! :)
+ DO_TEST("q35-virtio-pci", + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM, + QEMU_CAPS_NETDEV, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL, + QEMU_CAPS_VIRTIO_KEYBOARD, + QEMU_CAPS_VIRTIO_MOUSE, + QEMU_CAPS_VIRTIO_TABLET, + QEMU_CAPS_VIRTIO_INPUT_HOST, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_FSDEV, + QEMU_CAPS_FSDEV_WRITEOUT, + 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); DO_TEST("pcie-root-port", QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
I didn't go through the test suite additions in detail, because when I tried I got cross-eyed very quickly. Plus, I assume you already verified the output of the tests make sense. I'll give it a closer look in the respin. -- Andrea Bolognani / Red Hat / Virtualization

On 08/16/2016 01:29 PM, Andrea Bolognani wrote:
On Mon, 2016-08-15 at 01:50 -0400, Laine Stump wrote:
libvirt previously assigned nearly all devices to a hotpluggable legacy PCI slot even on machines with a PCIe root complex. Doing this means that the domain will need a dmi-to-pci-bridge (to convert from PCIe to legacy PCI) and a pci-bridge (to provide hotpluggable legacy PCI slots.
To help reduce the need for these legacy controllers, this patch checks for the QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY capability (if that capability is present, then all virtio devices will automatically present as PCIe when attached to a PCIe controller, or PCI when attached to a legacy PCI controller), and assigns virtio devices to a hotpluggable PCIe slot instead.
NB: since the slot must be hotpluggable, and pcie-root (the PCIe root complex) does *not* support hotplug, this means that suitable controllers must also be in the config (i.e. either pcie-root-port, or pcie-downstream-port). For now, libvirt doesn't add those automatically, so if you put virtio devices in a config for a qemu that has PCIe-capable virtio devices, you'll need to add extra pcie-root-ports yourself. That requirement will be eliminated in a future patch, but for now, it's simple to do this:
<controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> ...
Partially Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1330024 --- [...]
@@ -1021,17 +1028,22 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, } }
- /* all other devices that plug into a PCI slot are treated as a - * PCI endpoint devices that require a hotplug-capable slot - * (except for some special cases which have specific handling - * below) + pciFlags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + pcieFlags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCIE_DEVICE; Blank line here.
+ /* if qemu has the disable-legacy option for + * virtio-net, then its virtio devices will present + * themselves as PCIe devices when plugged into a PCIe + * slot, so we can safely assign them to a PCIe slot. */ - flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + virtioFlags = havePCIeRoot && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY) ? + pcieFlags : pciFlags; How about unpacking that? I feel like
if (havePCIeRoot && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY)) { virtioFlags = pcieFlags; } else { virtioFlags = pciFlags; }
would be more readable and maintainable.
Sure.
for (i = 0; i < def->nfss; i++) { if (!virDeviceInfoPCIAddressWanted(&def->fss[i]->info)) continue;
+ flags = virtioFlags;
Blank line here.
/* Only support VirtIO-9p-pci so far. If that changes, * we might need to skip devices here */ if (virDomainPCIAddressReserveNextSlot(addrs, &def->fss[i]->info, @@ -1045,12 +1057,18 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, * in hostdevs list anyway, so handle them with other hostdevs * instead of here. */ - if ((def->nets[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || - !virDeviceInfoPCIAddressWanted(&def->nets[i]->info)) { + virDomainNetDefPtr net = def->nets[i]; + + if ((net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || + !virDeviceInfoPCIAddressWanted(&net->info)) { continue; } - if (virDomainPCIAddressReserveNextSlot(addrs, &def->nets[i]->info, - flags) < 0)
Blank line here.
+ if (STREQ(net->model, "virtio")) + flags = virtioFlags; + else + flags = pciFlags; It's kind of insane that we don't have a virDomainNetModel enum for this sort of check, isn't it?
Yes. It's just always been that way and nobody's done anything about it.
+ + if (virDomainPCIAddressReserveNextSlot(addrs, &net->info, flags) < 0) goto error; }
@@ -1064,6 +1082,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_USB) continue;
+ flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->sounds[i]->info, flags) < 0) goto error; @@ -1094,6 +1113,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, if (!virDeviceInfoPCIAddressWanted(&def->controllers[i]->info)) continue;
+ flags = pciFlags; Blank line here.
/* USB2 needs special handling to put all companions in the same slot */ if (IS_USB2_CONTROLLER(def->controllers[i])) { virPCIDeviceAddress addr = { 0, 0, 0, 0, false }; @@ -1150,6 +1170,12 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; def->controllers[i]->info.addr.pci = addr; } else { + if ((def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI && + def->controllers[i]->model == + VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI) || + (def->controllers[i]->type == + VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL)) + flags = virtioFlags;
This is one of those times I really wish our coding style guidelines allowed us to go past 80 columns :)
Yep. Sometimes it's impossible to follow anyway (if a single identifier by itself on the line goes past column 80).
[...]
@@ -1284,6 +1323,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, !virDeviceInfoPCIAddressWanted(&chr->info)) continue;
+ flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &chr->info, flags) < 0) goto error; } Having gotten this far, I wonder if the pattern used here couldn't be semplified a bit... Try squashing in the attached patch, see if you like it.
Yeah, I actually thought of doing something like that fairly late in the process after I saw what it had turned into, but decided not to mostly because I needed to settle on "something". I'll squash in your patch.
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml new file mode 100644 index 0000000..7bed08c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml As you mention in the test programs below, qemuxml2argv-q35-virtio-pci.xml and qemuxml2argv-q35-pcie.xml have the exact same contents.
Please make one of them a symbolic link to the other one, to save space and ensure they will remain in sync.
Sure. I didn't realize that was "a thing", but I see now there are two other examples of symlinking test files already.
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args new file mode 100644 index 0000000..c43c537 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pcie.args This looks like a leftover from a previous attempt, and in fact 'make check' still passes after deleting it.
You are correct. I decided to rename the test case so that it could be used to test *all* pcie devices, not just virtio pcie, but blindly added all the new files to the commit.
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ad0693f..46b602f 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -607,7 +607,6 @@ mymain(void) unsetenv("QEMU_AUDIO_DRV"); unsetenv("SDL_AUDIODRIVER");
- DO_TEST("minimal", NONE); No reason to delete this AFAICT.
Yep. That was accidental.
DO_TEST_PARSE_ERROR("minimal-no-memory", NONE); DO_TEST("minimal-msg-timestamp", QEMU_CAPS_MSG_TIMESTAMP); DO_TEST("machine-aliases1", NONE); @@ -1670,6 +1669,48 @@ mymain(void) 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-pcie", + QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM, + QEMU_CAPS_NETDEV, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL, + QEMU_CAPS_VIRTIO_KEYBOARD, + QEMU_CAPS_VIRTIO_MOUSE, + QEMU_CAPS_VIRTIO_TABLET, + QEMU_CAPS_VIRTIO_INPUT_HOST, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_FSDEV, + QEMU_CAPS_FSDEV_WRITEOUT, + 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); + /* same XML as q35-pcie, but don't set QEMU_CAPS_VIRTIO_PCI_LEGACY */
This is really nice. We have a bunch of tests where the name is not that helpful in conveying exactly what they're supposed to be testing... Actually, adding a few words for q35-pcie would be even nicer! :)
+ DO_TEST("q35-virtio-pci", + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_RNG_RANDOM, + QEMU_CAPS_NETDEV, + QEMU_CAPS_DEVICE_VIRTIO_NET, + QEMU_CAPS_DEVICE_VIRTIO_GPU, + QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL, + QEMU_CAPS_VIRTIO_KEYBOARD, + QEMU_CAPS_VIRTIO_MOUSE, + QEMU_CAPS_VIRTIO_TABLET, + QEMU_CAPS_VIRTIO_INPUT_HOST, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_FSDEV, + QEMU_CAPS_FSDEV_WRITEOUT, + 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); DO_TEST("pcie-root-port", QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, I didn't go through the test suite additions in detail, because when I tried I got cross-eyed very quickly. Plus, I assume you already verified the output of the tests make sense. I'll give it a closer look in the respin.
-- Andrea Bolognani / Red Hat / Virtualization

The e1000e is an emulated network device based on the Intel 82574, present in qemu 2.7.0 and later. Among other differences from the e1000, it presents itself as a PCIe device rather than legacy PCI. In order to get it assigned to a PCIe controller, this patch updates the flags setting for network devices when the model name is "e1000e". (Note that for some reason libvirt has never validated the network device model names other than to check that there are no dangerous characters in them. That should probably change, but is the subject of another patch.) Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1343094 --- src/qemu/qemu_domain_address.c | 2 ++ tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 24 +++++++++++-------- tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml | 5 ++++ .../qemuxml2argv-q35-virtio-pci.args | 4 ++++ .../qemuxml2argv-q35-virtio-pci.xml | 5 ++++ .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 28 +++++++++++++++------- .../qemuxml2xmlout-q35-virtio-pci.xml | 10 ++++++++ 7 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 49181d1..9898eef 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1065,6 +1065,8 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, } if (STREQ(net->model, "virtio")) flags = virtioFlags; + else if (havePCIeRoot && STREQ(net->model, "e1000e")) + flags = pcieFlags; else flags = pciFlags; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args index 2ea0c08..40c8063 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args @@ -29,15 +29,16 @@ QEMU_AUDIO_DRV=none \ -device ioh3420,port=0x50,chassis=11,id=pci.11,bus=pcie.0,addr=0xa \ -device ioh3420,port=0x58,chassis=12,id=pci.12,bus=pcie.0,addr=0xb \ -device ioh3420,port=0x60,chassis=13,id=pci.13,bus=pcie.0,addr=0xc \ +-device ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ -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 virtio-scsi-pci,id=scsi0,bus=pci.6,addr=0x0 \ --device virtio-serial-pci,id=virtio-serial0,bus=pci.5,addr=0x0 \ +-device virtio-scsi-pci,id=scsi0,bus=pci.7,addr=0x0 \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.6,addr=0x0 \ -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk1 \ --device virtio-blk-pci,bus=pci.7,addr=0x0,drive=drive-virtio-disk1,\ +-device virtio-blk-pci,bus=pci.8,addr=0x0,drive=drive-virtio-disk1,\ id=virtio-disk1 \ -fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/to/guest \ -device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=/import/from/host,\ @@ -45,13 +46,16 @@ bus=pci.3,addr=0x0 \ -netdev user,id=hostnet0 \ -device virtio-net-pci,netdev=hostnet0,id=net0,mac=00:11:22:33:44:55,bus=pci.4,\ addr=0x0 \ --device virtio-input-host-pci,id=input0,evdev=/dev/input/event1234,bus=pci.10,\ +-netdev user,id=hostnet1 \ +-device e1000e,netdev=hostnet1,id=net1,mac=00:11:22:33:44:66,bus=pci.5,\ addr=0x0 \ --device virtio-mouse-pci,id=input1,bus=pci.11,addr=0x0 \ --device virtio-keyboard-pci,id=input2,bus=pci.12,addr=0x0 \ --device virtio-tablet-pci,id=input3,bus=pci.13,addr=0x0 \ +-device virtio-input-host-pci,id=input0,evdev=/dev/input/event1234,bus=pci.11,\ +addr=0x0 \ +-device virtio-mouse-pci,id=input1,bus=pci.12,addr=0x0 \ +-device virtio-keyboard-pci,id=input2,bus=pci.13,addr=0x0 \ +-device virtio-tablet-pci,id=input3,bus=pci.14,addr=0x0 \ -device virtio-vga,id=video0,bus=pcie.0,addr=0x1 \ --device virtio-balloon-pci,id=balloon0,bus=pci.8,addr=0x0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.9,addr=0x0 \ -object rng-random,id=objrng0,filename=/dev/urandom \ --device virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=123,period=1234,bus=pci.9,\ -addr=0x0 +-device virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=123,period=1234,\ +bus=pci.10,addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml index 7bed08c..39db5f0 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml @@ -28,6 +28,7 @@ <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> <controller type='virtio-serial'/> <controller type='scsi' model='virtio-scsi'/> <disk type='block' device='disk'> @@ -45,6 +46,10 @@ <mac address='00:11:22:33:44:55'/> <model type='virtio'/> </interface> + <interface type='user'> + <mac address='00:11:22:33:44:66'/> + <model type='e1000e'/> + </interface> <memballoon model='virtio'/> <rng model='virtio'> <rate bytes='123' period='1234'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args index 7cedc82..5723af7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args @@ -29,6 +29,7 @@ QEMU_AUDIO_DRV=none \ -device ioh3420,port=0x50,chassis=11,id=pci.11,bus=pcie.0,addr=0xa \ -device ioh3420,port=0x58,chassis=12,id=pci.12,bus=pcie.0,addr=0xb \ -device ioh3420,port=0x60,chassis=13,id=pci.13,bus=pcie.0,addr=0xc \ +-device ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ -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 \ @@ -45,6 +46,9 @@ bus=pci.2,addr=0x1 \ -netdev user,id=hostnet0 \ -device virtio-net-pci,netdev=hostnet0,id=net0,mac=00:11:22:33:44:55,bus=pci.2,\ addr=0x2 \ +-netdev user,id=hostnet1 \ +-device e1000e,netdev=hostnet1,id=net1,mac=00:11:22:33:44:66,bus=pci.3,\ +addr=0x0 \ -device virtio-input-host-pci,id=input0,evdev=/dev/input/event1234,bus=pci.2,\ addr=0x8 \ -device virtio-mouse-pci,id=input1,bus=pci.2,addr=0x9 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml index 7bed08c..39db5f0 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml @@ -28,6 +28,7 @@ <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> <controller type='virtio-serial'/> <controller type='scsi' model='virtio-scsi'/> <disk type='block' device='disk'> @@ -45,6 +46,10 @@ <mac address='00:11:22:33:44:55'/> <model type='virtio'/> </interface> + <interface type='user'> + <mac address='00:11:22:33:44:66'/> + <model type='e1000e'/> + </interface> <memballoon model='virtio'/> <rng model='virtio'> <rate bytes='123' period='1234'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml index 60e29b5..5a23a51 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml @@ -17,7 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='vdb' bus='virtio'/> - <address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/> </disk> <controller type='pci' index='0' model='pcie-root'/> <controller type='pci' index='1' model='dmi-to-pci-bridge'> @@ -84,11 +84,16 @@ <target chassis='13' port='0x60'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> </controller> + <controller type='pci' index='14' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='14' port='0x68'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/> + </controller> <controller type='virtio-serial' index='0'> - <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> </controller> <controller type='scsi' index='0' model='virtio-scsi'> - <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/> </controller> <controller type='usb' index='0' model='ich9-ehci1'> <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> @@ -118,18 +123,23 @@ <model type='virtio'/> <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> </interface> + <interface type='user'> + <mac address='00:11:22:33:44:66'/> + <model type='e1000e'/> + <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> + </interface> <input type='passthrough' bus='virtio'> <source evdev='/dev/input/event1234'/> - <address type='pci' domain='0x0000' bus='0x0a' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0b' slot='0x00' function='0x0'/> </input> <input type='mouse' bus='virtio'> - <address type='pci' domain='0x0000' bus='0x0b' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0c' slot='0x00' function='0x0'/> </input> <input type='keyboard' bus='virtio'> - <address type='pci' domain='0x0000' bus='0x0c' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0d' slot='0x00' function='0x0'/> </input> <input type='tablet' bus='virtio'> - <address type='pci' domain='0x0000' bus='0x0d' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0e' slot='0x00' function='0x0'/> </input> <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> @@ -138,12 +148,12 @@ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> </video> <memballoon model='virtio'> - <address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x09' slot='0x00' function='0x0'/> </memballoon> <rng model='virtio'> <rate bytes='123' period='1234'/> <backend model='random'>/dev/urandom</backend> - <address type='pci' domain='0x0000' bus='0x09' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0a' slot='0x00' function='0x0'/> </rng> </devices> </domain> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml index 5c5acac..22c2c68 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml @@ -84,6 +84,11 @@ <target chassis='13' port='0x60'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> </controller> + <controller type='pci' index='14' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='14' port='0x68'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/> + </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0'/> </controller> @@ -118,6 +123,11 @@ <model type='virtio'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x0'/> </interface> + <interface type='user'> + <mac address='00:11:22:33:44:66'/> + <model type='e1000e'/> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> + </interface> <input type='passthrough' bus='virtio'> <source evdev='/dev/input/event1234'/> <address type='pci' domain='0x0000' bus='0x02' slot='0x08' function='0x0'/> -- 2.7.4

On Mon, 2016-08-15 at 01:50 -0400, Laine Stump wrote:
The e1000e is an emulated network device based on the Intel 82574, present in qemu 2.7.0 and later. Among other differences from the e1000, it presents itself as a PCIe device rather than legacy PCI. In order to get it assigned to a PCIe controller, this patch updates the flags setting for network devices when the model name is "e1000e".
(Note that for some reason libvirt has never validated the network device model names other than to check that there are no dangerous characters in them. That should probably change, but is the subject of another patch.)
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1343094 --- src/qemu/qemu_domain_address.c | 2 ++ tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 24 +++++++++++-------- tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml | 5 ++++ .../qemuxml2argv-q35-virtio-pci.args | 4 ++++ .../qemuxml2argv-q35-virtio-pci.xml | 5 ++++ .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 28 +++++++++++++++------- .../qemuxml2xmlout-q35-virtio-pci.xml | 10 ++++++++ 7 files changed, 59 insertions(+), 19 deletions(-)
ACK -- Andrea Bolognani / Red Hat / Virtualization

The nec-usb-xhci device (which is a USB3 controller) has always presented itself as a PCI device when plugged into a legacy PCI slot, and a PCIe device when plugged into a PCIe slot, but libvirt has always auto-assigned it to a PCI slot. This patch changes that behavior to auto-assign to a PCIe slot on systems that have pcie-root (e.g. Q35 and aarch64/virt). Since we don't yet auto-create pcie-*-port controllers on demand, this means a config with an nec-xhci USB controller that has no PCI address assigned will also need to have an otherwise-unused pcie-*-port controller specified: <controller type='pci' model='pcie-root-port'/> <controller type='usb' model='nec-xhci'/> (this assumes there is an otherwise-unused slot on pcie-root to accept the pcie-root-port) --- src/qemu/qemu_domain_address.c | 7 +++++ tests/qemuxml2argvdata/qemuxml2argv-autoindex.args | 10 +++---- tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 21 ++++++------- tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml | 2 ++ .../qemuxml2argv-q35-virtio-pci.args | 7 ++--- .../qemuxml2argv-q35-virtio-pci.xml | 2 ++ tests/qemuxml2argvtest.c | 2 ++ .../qemuxml2xmlout-autoindex.xml | 10 +++---- .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 35 +++++++++------------- .../qemuxml2xmlout-q35-virtio-pci.xml | 21 +++++-------- 10 files changed, 55 insertions(+), 62 deletions(-) diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 9898eef..2c1341e 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1178,6 +1178,13 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL)) flags = virtioFlags; + else if (havePCIeRoot && + def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && + def->controllers[i]->model == + VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI) + flags = pcieFlags; + else + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->controllers[i]->info, flags) < 0) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-autoindex.args b/tests/qemuxml2argvdata/qemuxml2argv-autoindex.args index 43b9661..fc14dc4 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-autoindex.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-autoindex.args @@ -43,11 +43,11 @@ 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 \ -device ich9-usb-ehci1,id=usb2,bus=pci.2,addr=0x1.0x7 \ --device nec-usb-xhci,id=usb3,bus=pci.2,addr=0x2 \ +-device nec-usb-xhci,id=usb3,bus=pci.5,addr=0x0 \ -device ich9-usb-uhci1,masterbus=usb4.0,firstport=0,bus=pci.2,multifunction=on,\ -addr=0x3 \ --device ich9-usb-uhci2,masterbus=usb4.0,firstport=2,bus=pci.2,addr=0x3.0x1 \ --device ich9-usb-uhci3,masterbus=usb4.0,firstport=4,bus=pci.2,addr=0x3.0x2 \ --device ich9-usb-ehci1,id=usb4,bus=pci.2,addr=0x3.0x7 \ +addr=0x2 \ +-device ich9-usb-uhci2,masterbus=usb4.0,firstport=2,bus=pci.2,addr=0x2.0x1 \ +-device ich9-usb-uhci3,masterbus=usb4.0,firstport=4,bus=pci.2,addr=0x2.0x2 \ +-device ich9-usb-ehci1,id=usb4,bus=pci.2,addr=0x2.0x7 \ -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 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args index 40c8063..059b232 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args @@ -30,15 +30,12 @@ QEMU_AUDIO_DRV=none \ -device ioh3420,port=0x58,chassis=12,id=pci.12,bus=pcie.0,addr=0xb \ -device ioh3420,port=0x60,chassis=13,id=pci.13,bus=pcie.0,addr=0xc \ -device ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ --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 ioh3420,port=0x70,chassis=15,id=pci.15,bus=pcie.0,addr=0xe \ +-device nec-usb-xhci,id=usb,bus=pci.8,addr=0x0 \ -device virtio-scsi-pci,id=scsi0,bus=pci.7,addr=0x0 \ -device virtio-serial-pci,id=virtio-serial0,bus=pci.6,addr=0x0 \ -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk1 \ --device virtio-blk-pci,bus=pci.8,addr=0x0,drive=drive-virtio-disk1,\ +-device virtio-blk-pci,bus=pci.9,addr=0x0,drive=drive-virtio-disk1,\ id=virtio-disk1 \ -fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/to/guest \ -device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=/import/from/host,\ @@ -49,13 +46,13 @@ addr=0x0 \ -netdev user,id=hostnet1 \ -device e1000e,netdev=hostnet1,id=net1,mac=00:11:22:33:44:66,bus=pci.5,\ addr=0x0 \ --device virtio-input-host-pci,id=input0,evdev=/dev/input/event1234,bus=pci.11,\ +-device virtio-input-host-pci,id=input0,evdev=/dev/input/event1234,bus=pci.12,\ addr=0x0 \ --device virtio-mouse-pci,id=input1,bus=pci.12,addr=0x0 \ --device virtio-keyboard-pci,id=input2,bus=pci.13,addr=0x0 \ --device virtio-tablet-pci,id=input3,bus=pci.14,addr=0x0 \ +-device virtio-mouse-pci,id=input1,bus=pci.13,addr=0x0 \ +-device virtio-keyboard-pci,id=input2,bus=pci.14,addr=0x0 \ +-device virtio-tablet-pci,id=input3,bus=pci.15,addr=0x0 \ -device virtio-vga,id=video0,bus=pcie.0,addr=0x1 \ --device virtio-balloon-pci,id=balloon0,bus=pci.9,addr=0x0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.10,addr=0x0 \ -object rng-random,id=objrng0,filename=/dev/urandom \ -device virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=123,period=1234,\ -bus=pci.10,addr=0x0 +bus=pci.11,addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml index 39db5f0..b6b971b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml @@ -29,8 +29,10 @@ <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> <controller type='virtio-serial'/> <controller type='scsi' model='virtio-scsi'/> + <controller type='usb' model='nec-xhci'/> <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='vdb' bus='virtio'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args index 5723af7..a9a760f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args @@ -30,11 +30,8 @@ QEMU_AUDIO_DRV=none \ -device ioh3420,port=0x58,chassis=12,id=pci.12,bus=pcie.0,addr=0xb \ -device ioh3420,port=0x60,chassis=13,id=pci.13,bus=pcie.0,addr=0xc \ -device ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ --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 ioh3420,port=0x70,chassis=15,id=pci.15,bus=pcie.0,addr=0xe \ +-device nec-usb-xhci,id=usb,bus=pci.4,addr=0x0 \ -device virtio-scsi-pci,id=scsi0,bus=pci.2,addr=0x4 \ -device virtio-serial-pci,id=virtio-serial0,bus=pci.2,addr=0x3 \ -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk1 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml index 39db5f0..b6b971b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.xml @@ -29,8 +29,10 @@ <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-root-port'/> + <controller type='pci' model='pcie-root-port'/> <controller type='virtio-serial'/> <controller type='scsi' model='virtio-scsi'/> + <controller type='usb' model='nec-xhci'/> <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='vdb' bus='virtio'/> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 46b602f..31b2aee 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1689,6 +1689,7 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_ICH9_AHCI, QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1, + QEMU_CAPS_NEC_USB_XHCI, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); /* same XML as q35-pcie, but don't set QEMU_CAPS_VIRTIO_PCI_LEGACY */ DO_TEST("q35-virtio-pci", @@ -1710,6 +1711,7 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_ICH9_AHCI, QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1, + QEMU_CAPS_NEC_USB_XHCI, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); DO_TEST("pcie-root-port", QEMU_CAPS_DEVICE_PCI_BRIDGE, diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-autoindex.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-autoindex.xml index 086a1cf..2a8a44a 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-autoindex.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-autoindex.xml @@ -126,22 +126,22 @@ <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x7'/> </controller> <controller type='usb' index='3' model='nec-xhci'> - <address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> </controller> <controller type='usb' index='4' model='ich9-uhci1'> <master startport='0'/> - <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0' multifunction='on'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x0' multifunction='on'/> </controller> <controller type='usb' index='4' model='ich9-uhci2'> <master startport='2'/> - <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x1'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x1'/> </controller> <controller type='usb' index='4' model='ich9-uhci3'> <master startport='4'/> - <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x2'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x2'/> </controller> <controller type='usb' index='4' model='ich9-ehci1'> - <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x7'/> + <address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x7'/> </controller> <controller type='sata' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml index 5a23a51..8e727fb 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml @@ -17,7 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='vdb' bus='virtio'/> - <address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x09' slot='0x00' function='0x0'/> </disk> <controller type='pci' index='0' model='pcie-root'/> <controller type='pci' index='1' model='dmi-to-pci-bridge'> @@ -89,26 +89,19 @@ <target chassis='14' port='0x68'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/> </controller> + <controller type='pci' index='15' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='15' port='0x70'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0e' function='0x0'/> + </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> </controller> <controller type='scsi' index='0' model='virtio-scsi'> <address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/> </controller> - <controller type='usb' index='0' model='ich9-ehci1'> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> - </controller> - <controller type='usb' index='0' model='ich9-uhci1'> - <master startport='0'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/> - </controller> - <controller type='usb' index='0' model='ich9-uhci2'> - <master startport='2'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/> - </controller> - <controller type='usb' index='0' model='ich9-uhci3'> - <master startport='4'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/> + <controller type='usb' index='0' model='nec-xhci'> + <address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/> </controller> <controller type='sata' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> @@ -130,16 +123,16 @@ </interface> <input type='passthrough' bus='virtio'> <source evdev='/dev/input/event1234'/> - <address type='pci' domain='0x0000' bus='0x0b' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0c' slot='0x00' function='0x0'/> </input> <input type='mouse' bus='virtio'> - <address type='pci' domain='0x0000' bus='0x0c' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0d' slot='0x00' function='0x0'/> </input> <input type='keyboard' bus='virtio'> - <address type='pci' domain='0x0000' bus='0x0d' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0e' slot='0x00' function='0x0'/> </input> <input type='tablet' bus='virtio'> - <address type='pci' domain='0x0000' bus='0x0e' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0f' slot='0x00' function='0x0'/> </input> <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> @@ -148,12 +141,12 @@ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> </video> <memballoon model='virtio'> - <address type='pci' domain='0x0000' bus='0x09' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0a' slot='0x00' function='0x0'/> </memballoon> <rng model='virtio'> <rate bytes='123' period='1234'/> <backend model='random'>/dev/urandom</backend> - <address type='pci' domain='0x0000' bus='0x0a' slot='0x00' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x0b' slot='0x00' function='0x0'/> </rng> </devices> </domain> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml index 22c2c68..c4bd357 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml @@ -89,26 +89,19 @@ <target chassis='14' port='0x68'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/> </controller> + <controller type='pci' index='15' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='15' port='0x70'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0e' function='0x0'/> + </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0'/> </controller> <controller type='scsi' index='0' model='virtio-scsi'> <address type='pci' domain='0x0000' bus='0x02' slot='0x04' function='0x0'/> </controller> - <controller type='usb' index='0' model='ich9-ehci1'> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> - </controller> - <controller type='usb' index='0' model='ich9-uhci1'> - <master startport='0'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/> - </controller> - <controller type='usb' index='0' model='ich9-uhci2'> - <master startport='2'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/> - </controller> - <controller type='usb' index='0' model='ich9-uhci3'> - <master startport='4'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/> + <controller type='usb' index='0' model='nec-xhci'> + <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> </controller> <controller type='sata' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> -- 2.7.4

On Mon, 2016-08-15 at 01:50 -0400, Laine Stump wrote:
The nec-usb-xhci device (which is a USB3 controller) has always presented itself as a PCI device when plugged into a legacy PCI slot, and a PCIe device when plugged into a PCIe slot, but libvirt has always auto-assigned it to a PCI slot. This patch changes that behavior to auto-assign to a PCIe slot on systems that have pcie-root (e.g. Q35 and aarch64/virt). Since we don't yet auto-create pcie-*-port controllers on demand, this means a config with an nec-xhci USB controller that has no PCI address assigned will also need to have an otherwise-unused pcie-*-port controller specified: <controller type='pci' model='pcie-root-port'/> <controller type='usb' model='nec-xhci'/> (this assumes there is an otherwise-unused slot on pcie-root to accept the pcie-root-port) --- src/qemu/qemu_domain_address.c | 7 +++++ tests/qemuxml2argvdata/qemuxml2argv-autoindex.args | 10 +++---- tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 21 ++++++------- tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.xml | 2 ++ .../qemuxml2argv-q35-virtio-pci.args | 7 ++--- .../qemuxml2argv-q35-virtio-pci.xml | 2 ++ tests/qemuxml2argvtest.c | 2 ++ .../qemuxml2xmlout-autoindex.xml | 10 +++---- .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 35 +++++++++------------- .../qemuxml2xmlout-q35-virtio-pci.xml | 21 +++++-------- 10 files changed, 55 insertions(+), 62 deletions(-) diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 9898eef..2c1341e 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1178,6 +1178,13 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL)) flags = virtioFlags; + else if (havePCIeRoot && + def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
This goes over 80 columns, so it will have to be split. Which of course makes the whole thing nearly unreadable :(
+ def->controllers[i]->model == + VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI) + flags = pcieFlags; + else + flags = pciFlags; if (virDomainPCIAddressReserveNextSlot(addrs, &def->controllers[i]->info, flags) < 0)
ACK -- Andrea Bolognani / Red Hat / Virtualization
participants (2)
-
Andrea Bolognani
-
Laine Stump