[libvirt] [PATCH v3 0/8] aggregate multiple pcie-root-ports onto a single slot

Another rebase of the series with no other changes Laine Stump (8): conf: use struct instead of int for each slot in virDomainPCIAddressBus conf: eliminate concept of "reserveEntireSlot" conf: eliminate repetitive code in virDomainPCIAddressGetNextSlot() conf: start search for next unused PCI address at same slot as previous find conf: new function virDomainPCIAddressIsMulti() qemu: use virDomainPCIAddressIsMulti() to determine multifunction setting conf: aggregate multiple devices on a slot when assigning PCI addresses conf: aggregate multiple pcie-root-ports onto a single slot src/conf/domain_addr.c | 290 ++++++++++++++------- src/conf/domain_addr.h | 48 +++- src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 16 +- src/qemu/qemu_domain_address.c | 35 ++- .../qemuxml2argv-pcie-root-port.args | 5 +- .../qemuxml2argv-pcie-switch-upstream-port.args | 5 +- .../qemuxml2argv-q35-default-devices-only.args | 7 +- .../qemuxml2argv-q35-multifunction.args | 43 +++ .../qemuxml2argv-q35-multifunction.xml | 51 ++++ .../qemuxml2argv-q35-pcie-autoadd.args | 30 ++- tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 28 +- .../qemuxml2argv-q35-virt-manager-basic.args | 13 +- .../qemuxml2argv-q35-virtio-pci.args | 28 +- tests/qemuxml2argvtest.c | 25 ++ .../qemuxml2xmlout-pcie-root-port.xml | 2 +- .../qemuxml2xmlout-pcie-switch-upstream-port.xml | 4 +- .../qemuxml2xmlout-q35-default-devices-only.xml | 8 +- .../qemuxml2xmlout-q35-multifunction.xml | 120 +++++++++ .../qemuxml2xmlout-q35-pcie-autoadd.xml | 52 ++-- .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 48 ++-- .../qemuxml2xmlout-q35-virt-manager-basic.xml | 20 +- .../qemuxml2xmlout-q35-virtio-pci.xml | 48 ++-- tests/qemuxml2xmltest.c | 25 ++ 24 files changed, 676 insertions(+), 276 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml -- 2.7.4

When keeping track of which functions of which slots are allocated, we will need to have more information than just the current bitmap with a bit for each function that is currently stored for each slot in a virDomainPCIAddressBus. To prepare for adding more per-slot info, this patch changes "int slots" into "virDomainPCIAddressSlot slot", which currently has a single member named "functions" that serves the same purpose previously served directly by "slots". --- src/conf/domain_addr.c | 15 ++++++++------- src/conf/domain_addr.h | 9 ++++++++- src/qemu/qemu_domain_address.c | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index b64fc18..1ceb4e2 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -522,7 +522,7 @@ bool virDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr) { - return !!addrs->buses[addr->bus].slots[addr->slot]; + return !!addrs->buses[addr->bus].slot[addr->slot].functions; } @@ -563,17 +563,17 @@ virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, bus = &addrs->buses[addr->bus]; if (reserveEntireSlot) { - if (bus->slots[addr->slot]) { + if (bus->slot[addr->slot].functions) { virReportError(errType, _("Attempted double use of PCI slot %s " "(may need \"multifunction='on'\" for " "device on function 0)"), addrStr); goto cleanup; } - bus->slots[addr->slot] = 0xFF; /* reserve all functions of slot */ + bus->slot[addr->slot].functions = 0xFF; /* reserve all functions of slot */ VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", addrStr); } else { - if (bus->slots[addr->slot] & (1 << addr->function)) { + if (bus->slot[addr->slot].functions & (1 << addr->function)) { if (addr->function == 0) { virReportError(errType, _("Attempted double use of PCI Address %s"), @@ -586,7 +586,7 @@ virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, } goto cleanup; } - bus->slots[addr->slot] |= (1 << addr->function); + bus->slot[addr->slot].functions |= (1 << addr->function); VIR_DEBUG("Reserving PCI address %s", addrStr); } @@ -653,7 +653,8 @@ int virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr) { - addrs->buses[addr->bus].slots[addr->slot] &= ~(1 << addr->function); + addrs->buses[addr->bus].slot[addr->slot].functions + &= ~(1 << addr->function); return 0; } @@ -674,7 +675,7 @@ virDomainPCIAddressReleaseSlot(virDomainPCIAddressSetPtr addrs, if (!virDomainPCIAddressValidate(addrs, addr, addrStr, flags, false)) goto cleanup; - addrs->buses[addr->bus].slots[addr->slot] = 0; + addrs->buses[addr->bus].slot[addr->slot].functions = 0; ret = 0; cleanup: VIR_FREE(addrStr); diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index bcec2c7..7df0502 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -71,6 +71,13 @@ virDomainPCIConnectFlags virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model); typedef struct { + /* each function is represented by one it, set if that function is + * in use by a device, or clear if it isn't. + */ + uint8_t functions; + } virDomainPCIAddressSlot; + +typedef struct { virDomainControllerModelPCI model; /* flags and min/max can be computed from model, but * having them ready makes life easier. @@ -80,7 +87,7 @@ typedef struct { /* Each bit in a slot represents one function on that slot. If the * bit is set, that function is in use by a device. */ - uint8_t slots[VIR_PCI_ADDRESS_SLOT_LAST + 1]; + virDomainPCIAddressSlot slot[VIR_PCI_ADDRESS_SLOT_LAST + 1]; } virDomainPCIAddressBus; typedef virDomainPCIAddressBus *virDomainPCIAddressBusPtr; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index be4ed23..39d2bc9 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1459,7 +1459,7 @@ qemuDomainPCIBusFullyReserved(virDomainPCIAddressBusPtr bus) size_t i; for (i = bus->minSlot; i <= bus->maxSlot; i++) - if (!bus->slots[i]) + if (!bus->slot[i].functions) return false; return true; -- 2.7.4

On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote:
When keeping track of which functions of which slots are allocated, we will need to have more information than just the current bitmap with a bit for each function that is currently stored for each slot in a virDomainPCIAddressBus. To prepare for adding more per-slot info, this patch changes "int slots" into "virDomainPCIAddressSlot slot", which
The original struct member was uint8_t rather than int. I also don't agree with the name change: "slots" is already a perfectly good name for an array of "virDomainPCIAddressSlot"s. [...]
@@ -653,7 +653,8 @@ int virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr) { - addrs->buses[addr->bus].slots[addr->slot] &= ~(1 << addr->function); + addrs->buses[addr->bus].slot[addr->slot].functions + &= ~(1 << addr->function);
Keep this on a single line. [...]
@@ -71,6 +71,13 @@ virDomainPCIConnectFlags virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model); typedef struct { + /* each function is represented by one it, set if that function is
s/by one it/by one bit/
+ * in use by a device, or clear if it isn't. + */ + uint8_t functions; + } virDomainPCIAddressSlot;
Weird indentation here. ACK with the nits fixed. -- Andrea Bolognani / Red Hat / Virtualization

setting reserveEntireSlot really accomplishes nothing - instead of going to the trouble of computing the value for reserveEntireSlot and then possibly setting *all* functions of the slot as in-use, we can just set the in-use bit only for the specific function being used by a device. Later we will know from the context (the PCI connect flags, and whether we are reserving a specific address or asking for "the next available") whether or not it is okay to allocate other functions on the same slot. Although it's not used yet, we allow specifying "-1" for the function number when looking for the "next available slot" - this is going to end up meaning "return the lowest avaialable function in the slot, but since we currently only provide a function from an otherwise unused slot, "-1" ends up meaning "0". --- src/conf/domain_addr.c | 76 ++++++++++++++++-------------------------- src/conf/domain_addr.h | 4 +-- src/qemu/qemu_domain_address.c | 33 ++++++++---------- 3 files changed, 43 insertions(+), 70 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 1ceb4e2..85517ea 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -527,11 +527,9 @@ virDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs, /* - * Reserve a slot (or just one function) for a device. If - * reserveEntireSlot is true, all functions for the slot are reserved, - * otherwise only one. If fromConfig is true, the address being - * requested came directly from the config and errors should be worded - * appropriately. If fromConfig is false, the address was + * Reserve a function in a slot. If fromConfig is true, the address + * being requested came directly from the config and errors should be + * worded appropriately. If fromConfig is false, the address was * automatically created by libvirt, so it is an internal error (not * XML). */ @@ -539,7 +537,6 @@ int virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr, virDomainPCIConnectFlags flags, - bool reserveEntireSlot, bool fromConfig) { int ret = -1; @@ -562,33 +559,13 @@ virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, bus = &addrs->buses[addr->bus]; - if (reserveEntireSlot) { - if (bus->slot[addr->slot].functions) { - virReportError(errType, - _("Attempted double use of PCI slot %s " - "(may need \"multifunction='on'\" for " - "device on function 0)"), addrStr); - goto cleanup; - } - bus->slot[addr->slot].functions = 0xFF; /* reserve all functions of slot */ - VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", addrStr); - } else { - if (bus->slot[addr->slot].functions & (1 << addr->function)) { - if (addr->function == 0) { - virReportError(errType, - _("Attempted double use of PCI Address %s"), - addrStr); - } else { - virReportError(errType, - _("Attempted double use of PCI Address %s " - "(may need \"multifunction='on'\" " - "for device on function 0)"), addrStr); - } - goto cleanup; - } - bus->slot[addr->slot].functions |= (1 << addr->function); - VIR_DEBUG("Reserving PCI address %s", addrStr); + if (bus->slot[addr->slot].functions & (1 << addr->function)) { + virReportError(errType, _("Attempted double use of PCI Address %s"), + addrStr); + goto cleanup; } + bus->slot[addr->slot].functions |= (1 << addr->function); + VIR_DEBUG("Reserving PCI address %s", addrStr); ret = 0; cleanup: @@ -602,7 +579,7 @@ virDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr, virDomainPCIConnectFlags flags) { - return virDomainPCIAddressReserveAddr(addrs, addr, flags, true, false); + return virDomainPCIAddressReserveAddr(addrs, addr, flags, false); } int @@ -637,8 +614,8 @@ virDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs, addrStr, flags, true)) goto cleanup; - ret = virDomainPCIAddressReserveAddr(addrs, &dev->addr.pci, flags, - true, true); + ret = virDomainPCIAddressReserveAddr(addrs, &dev->addr.pci, + flags, true); } else { ret = virDomainPCIAddressReserveNextSlot(addrs, dev, flags); } @@ -717,6 +694,7 @@ virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs) static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr next_addr, + int function, virDomainPCIConnectFlags flags) { /* default to starting the search for a free slot from @@ -744,6 +722,12 @@ virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs, a.slot = addrs->buses[0].minSlot; } + /* if the caller asks for "any function", give them function 0 */ + if (function == -1) + a.function = 0; + else + a.function = function; + while (a.bus < addrs->nbuses) { VIR_FREE(addrStr); if (!(addrStr = virDomainPCIAddressAsString(&a))) @@ -822,14 +806,13 @@ virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs, * @dev: virDomainDeviceInfo that should get the new address. * @flags: CONNECT_TYPE flags for the device that needs an address. * @function: which function on the slot to mark as reserved - * (if @reserveEntireSlot is false) - * @reserveEntireSlot: true to reserve all functions on the new slot, - * false to reserve just @function * * Find the next *completely unreserved* slot with compatible - * connection @flags, mark either one function or the entire - * slot as in-use (according to @function and @reserveEntireSlot), - * and set @dev->addr.pci with this newly reserved address. + * connection @flags, mark one function of the slot as in-use + * (according to @function), then set @dev->addr.pci with this newly + * reserved address. If @function is -1, then the lowest unused + * function of the slot will be reserved (and since we only look for + * completely unused slots, that means "0"). * * returns 0 on success, or -1 on failure. */ @@ -837,17 +820,14 @@ int virDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev, virDomainPCIConnectFlags flags, - unsigned int function, - bool reserveEntireSlot) + int function) { virPCIDeviceAddress addr; - if (virDomainPCIAddressGetNextSlot(addrs, &addr, flags) < 0) + if (virDomainPCIAddressGetNextSlot(addrs, &addr, function, flags) < 0) return -1; - addr.function = reserveEntireSlot ? 0 : function; - - if (virDomainPCIAddressReserveAddr(addrs, &addr, flags, reserveEntireSlot, false) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &addr, flags, false) < 0) return -1; addrs->lastaddr = addr; @@ -867,7 +847,7 @@ virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev, virDomainPCIConnectFlags flags) { - return virDomainPCIAddressReserveNextAddr(addrs, dev, flags, 0, true); + return virDomainPCIAddressReserveNextAddr(addrs, dev, flags, 0); } diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 7df0502..9c08274 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -141,7 +141,6 @@ int virDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs, int virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr addr, virDomainPCIConnectFlags flags, - bool reserveEntireSlot, bool fromConfig) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); @@ -166,8 +165,7 @@ int virDomainPCIAddressReleaseSlot(virDomainPCIAddressSetPtr addrs, int virDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev, virDomainPCIConnectFlags flags, - unsigned int function, - bool reserveEntireSlot) + int function) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); int virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs, diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 39d2bc9..4a2a489 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -892,12 +892,11 @@ qemuDomainFillDevicePCIConnectFlags(virDomainDefPtr def, static int qemuDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev, - unsigned int function, - bool reserveEntireSlot) + unsigned int function) { return virDomainPCIAddressReserveNextAddr(addrs, dev, dev->pciConnectFlags, - function, reserveEntireSlot); + function); } @@ -905,7 +904,7 @@ static int qemuDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev) { - return qemuDomainPCIAddressReserveNextAddr(addrs, dev, 0, true); + return qemuDomainPCIAddressReserveNextAddr(addrs, dev, 0); } @@ -918,7 +917,6 @@ qemuDomainCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, virDomainPCIAddressSetPtr addrs = opaque; int ret = -1; virPCIDeviceAddressPtr addr = &info->addr.pci; - bool entireSlot; if (!virDeviceInfoPCIAddressPresent(info) || ((device->type == VIR_DOMAIN_DEVICE_HOSTDEV) && @@ -991,12 +989,10 @@ qemuDomainCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, } } - entireSlot = (addr->function == 0 && - addr->multi != VIR_TRISTATE_SWITCH_ON); - - if (virDomainPCIAddressReserveAddr(addrs, addr, info->pciConnectFlags, - entireSlot, true) < 0) + if (virDomainPCIAddressReserveAddr(addrs, addr, + info->pciConnectFlags, true) < 0) { goto cleanup; + } ret = 0; cleanup: @@ -1284,7 +1280,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, } if (assign) { if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, - flags, false, true) < 0) + flags, true) < 0) goto cleanup; cont->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; cont->info.addr.pci.domain = 0; @@ -1307,7 +1303,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, tmp_addr.slot = 0x1E; if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, - flags, true, false) < 0) + flags, false) < 0) goto cleanup; cont->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; cont->info.addr.pci.domain = 0; @@ -1330,13 +1326,13 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, tmp_addr.slot = 0x1F; tmp_addr.function = 0; tmp_addr.multi = VIR_TRISTATE_SWITCH_ON; - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, - false, false) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, + flags, false) < 0) goto cleanup; tmp_addr.function = 3; tmp_addr.multi = VIR_TRISTATE_SWITCH_ABSENT; - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, - false, false) < 0) + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, + flags, false) < 0) goto cleanup; } @@ -1636,7 +1632,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, /* Reserve this function on the slot we found */ if (virDomainPCIAddressReserveAddr(addrs, &addr, cont->info.pciConnectFlags, - false, true) < 0) + true) < 0) goto error; cont->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; @@ -1645,8 +1641,7 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, /* This is the first part of the controller, so need * to find a free slot & then reserve this function */ if (qemuDomainPCIAddressReserveNextAddr(addrs, &cont->info, - addr.function, - false) < 0) { + addr.function) < 0) { goto error; } -- 2.7.4

On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote:
setting reserveEntireSlot really accomplishes nothing - instead of going to the trouble of computing the value for reserveEntireSlot and then possibly setting *all* functions of the slot as in-use, we can just set the in-use bit only for the specific function being used by a device. Later we will know from the context (the PCI connect flags, and whether we are reserving a specific address or asking for "the next available") whether or not it is okay to allocate other functions on the same slot. Although it's not used yet, we allow specifying "-1" for the function
number when looking for the "next available slot" - this is going to
end up meaning "return the lowest avaialable function in the slot, but
s/avaialable/available/ [...]
@@ -562,33 +559,13 @@ virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, bus = &addrs->buses[addr->bus]; - if (reserveEntireSlot) { - if (bus->slot[addr->slot].functions) { - virReportError(errType, - _("Attempted double use of PCI slot %s " - "(may need \"multifunction='on'\" for " - "device on function 0)"), addrStr); - goto cleanup; - } - bus->slot[addr->slot].functions = 0xFF; /* reserve all functions of slot */ - VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", addrStr); - } else { - if (bus->slot[addr->slot].functions & (1 << addr->function)) { - if (addr->function == 0) { - virReportError(errType, - _("Attempted double use of PCI Address %s"), - addrStr); - } else { - virReportError(errType, - _("Attempted double use of PCI Address %s " - "(may need \"multifunction='on'\" " - "for device on function 0)"), addrStr); - } - goto cleanup; - } - bus->slot[addr->slot].functions |= (1 << addr->function); - VIR_DEBUG("Reserving PCI address %s", addrStr); + if (bus->slot[addr->slot].functions & (1 << addr->function)) { + virReportError(errType, _("Attempted double use of PCI Address %s"), + addrStr);
I'd leave errType alone on the first line and put the remaining arguments on the second one, but it's merely a suggestion :) ACK -- Andrea Bolognani / Red Hat / Virtualization

virDomainPCIAddressGetNextSlot() starts searching from the last allocated address and goes to the end of all the buses, then goes back to the first bus and searchs from there up to the starting point (in case any address has been freed since the last time an address was allocated. The loops for these two are almost, but not exactly, the same, so they have remained as separate loops with the same code inside the loop. To lessen maintenance headaches, the identical code has been moved out into the function virDomainPCIAddressFindUnusedFunctionOnBus(), which is called in place of the loop contents. --- src/conf/domain_addr.c | 92 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 85517ea..1f72bda 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -691,6 +691,45 @@ virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs) } +static int +virDomainPCIAddressFindUnusedFunctionOnBus(virDomainPCIAddressBusPtr bus, + virPCIDeviceAddressPtr searchAddr, + int function ATTRIBUTE_UNUSED, + virDomainPCIConnectFlags flags, + bool *found) +{ + int ret = -1; + char *addrStr = NULL; + + *found = false; + + if (!(addrStr = virDomainPCIAddressAsString(searchAddr))) + goto cleanup; + + if (!virDomainPCIAddressFlagsCompatible(searchAddr, addrStr, bus->flags, + flags, false, false)) { + VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device", + searchAddr->domain, searchAddr->bus); + } else { + while (searchAddr->slot <= bus->maxSlot) { + if (bus->slot[searchAddr->slot].functions == 0) { + *found = true; + break; + } + + VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use", + searchAddr->domain, searchAddr->bus, searchAddr->slot); + searchAddr->slot++; + } + } + + ret = 0; + cleanup: + VIR_FREE(addrStr); + return ret; +} + + static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs, virPCIDeviceAddressPtr next_addr, @@ -700,8 +739,8 @@ virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs, /* default to starting the search for a free slot from * the first slot of domain 0 bus 0... */ - virPCIDeviceAddress a = {0}; - char *addrStr = NULL; + virPCIDeviceAddress a = { 0 }; + bool found = false; if (addrs->nbuses == 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("No PCI buses available")); @@ -729,24 +768,16 @@ virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs, a.function = function; while (a.bus < addrs->nbuses) { - VIR_FREE(addrStr); - if (!(addrStr = virDomainPCIAddressAsString(&a))) + if (virDomainPCIAddressFindUnusedFunctionOnBus(&addrs->buses[a.bus], + &a, function, + flags, &found) < 0) { goto error; - if (!virDomainPCIAddressFlagsCompatible(&a, addrStr, - addrs->buses[a.bus].flags, - flags, false, false)) { - VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device", - a.domain, a.bus); - } else { - while (a.slot <= addrs->buses[a.bus].maxSlot) { - if (!virDomainPCIAddressSlotInUse(addrs, &a)) - goto success; - - VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use", - a.domain, a.bus, a.slot); - a.slot++; - } } + + if (found) + goto success; + + /* nothing on this bus, go to the next bus */ if (++a.bus < addrs->nbuses) a.slot = addrs->buses[a.bus].minSlot; } @@ -763,38 +794,27 @@ virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs, /* Check the buses from 0 up to the last used one */ for (a.bus = 0; a.bus <= addrs->lastaddr.bus; a.bus++) { a.slot = addrs->buses[a.bus].minSlot; - VIR_FREE(addrStr); - if (!(addrStr = virDomainPCIAddressAsString(&a))) + + if (virDomainPCIAddressFindUnusedFunctionOnBus(&addrs->buses[a.bus], + &a, function, + flags, &found) < 0) { goto error; - if (!virDomainPCIAddressFlagsCompatible(&a, addrStr, - addrs->buses[a.bus].flags, - flags, false, false)) { - VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device", - a.domain, a.bus); - } else { - while (a.slot <= addrs->buses[a.bus].maxSlot) { - if (!virDomainPCIAddressSlotInUse(addrs, &a)) - goto success; - - VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use", - a.domain, a.bus, a.slot); - a.slot++; - } } + + if (found) + goto success; } } virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No more available PCI slots")); error: - VIR_FREE(addrStr); return -1; success: VIR_DEBUG("Found free PCI slot %.4x:%.2x:%.2x", a.domain, a.bus, a.slot); *next_addr = a; - VIR_FREE(addrStr); return 0; } -- 2.7.4

On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote:
virDomainPCIAddressGetNextSlot() starts searching from the last allocated address and goes to the end of all the buses, then goes back to the first bus and searchs from there up to the starting point (in
s/searchs/searches/ [...]
+static int +virDomainPCIAddressFindUnusedFunctionOnBus(virDomainPCIAddressBusPtr bus, + virPCIDeviceAddressPtr searchAddr, + int function ATTRIBUTE_UNUSED, + virDomainPCIConnectFlags flags, + bool *found)
Having some documentation for the function, especially what parts of @searchAddr are inspected and updated, and how @function is used - not at all right now, but that's going to change later in the series - would be great. Incidentally, and not relevant to this series, passing around partially filled-in virPCIDeviceAddress instances *and* some of the same data on the side sucks big time. I wonder if the whole thing could be improved by changing the struct members to to signed and having #define VIR_PCI_DEVICE_ADDRESS_UNDEFINED -1 or leave them as it is and use #define VIR_PCI_DEVICE_ADDRESS_UNDEFINED UINT_MAX instead. Either way, we'd have a way to tell whether each of the components has been initialized or is in need of a value without having to pass data out-of-band.
+{ + int ret = -1; + char *addrStr = NULL; + + *found = false; + + if (!(addrStr = virDomainPCIAddressAsString(searchAddr))) + goto cleanup; + + if (!virDomainPCIAddressFlagsCompatible(searchAddr, addrStr, bus->flags, + flags, false, false)) { + VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device", + searchAddr->domain, searchAddr->bus); + } else { + while (searchAddr->slot <= bus->maxSlot) { + if (bus->slot[searchAddr->slot].functions == 0) { + *found = true; + break; + } + + VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use", + searchAddr->domain, searchAddr->bus, searchAddr->slot); + searchAddr->slot++; + } + } + + ret = 0;
Empty line here.
+ cleanup: + VIR_FREE(addrStr); + return ret; +}
ACK -- Andrea Bolognani / Red Hat / Virtualization

There is a very slight time advantage to beginning the search for the next unused PCI address at the slot *after* the previous find (which is now used), but if we do that, we will miss allocating the other functions of the same slot (when we implement a VIR_PCI_CONNECT_AGGREGATE_SLOT flag to support that). --- src/conf/domain_addr.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 1f72bda..8cc30ee 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -748,18 +748,14 @@ virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs, } /* ...unless this search is for the exact same type of device as - * last time, then continue the search from the next slot after - * the previous match (the "next slot" may possibly be the first - * slot of the next bus). + * last time, then continue the search from the slot where we + * found the previous match (it's possible there will still be a + * function available on that slot). */ - if (flags == addrs->lastFlags) { + if (flags == addrs->lastFlags) a = addrs->lastaddr; - if (++a.slot > addrs->buses[a.bus].maxSlot && - ++a.bus < addrs->nbuses) - a.slot = addrs->buses[a.bus].minSlot; - } else { + else a.slot = addrs->buses[0].minSlot; - } /* if the caller asks for "any function", give them function 0 */ if (function == -1) -- 2.7.4

On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote:
There is a very slight time advantage to beginning the search for the next unused PCI address at the slot *after* the previous find (which is now used), but if we do that, we will miss allocating the other functions of the same slot (when we implement a VIR_PCI_CONNECT_AGGREGATE_SLOT flag to support that).
ACK -- Andrea Bolognani / Red Hat / Virtualization

This function iterates through all the devices in a domain to determine if the address it has been given is part of a "multifunction device" (i.e. multiple devices connected to different functions of the same slot). This implementation may seem a bit inefficient because it has to iterate through all the devices for each device that needs checking, but this really is our only option since the address allocation set isn't always available (and maybe not even exist at the time it's needed). --- src/conf/domain_addr.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_addr.h | 5 ++++ src/libvirt_private.syms | 1 + 3 files changed, 66 insertions(+) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 8cc30ee..b8a91d2 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -867,6 +867,66 @@ virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs, } +typedef struct { + virPCIDeviceAddressPtr addr; + bool isMulti; +} virDomainPCIAddressIsMultiIterData; + + +static int +virDomainPCIAddressIsMultiIter(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED, + virDomainDeviceInfoPtr info, + void *data) +{ + virDomainPCIAddressIsMultiIterData *context = data; + virPCIDeviceAddressPtr testAddr = context->addr; + virPCIDeviceAddressPtr thisAddr; + + if (!info || info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) + return 0; + + thisAddr = &info->addr.pci; + + if (thisAddr->domain == testAddr->domain && + thisAddr->bus == testAddr->bus && + thisAddr->slot == testAddr->slot && + thisAddr->function != testAddr->function) { + context->isMulti = true; + return -1; /* finish early, *NOT* an error */ + } + + return 0; +} + + +/** + * virDomainPCIAddressIsMulti(): + * + * @def: the domain definition whose devices need adjusting + * @addr: the address to check + * + * See if there is any PCI device in the domain with the same + * domain/bus/slot but different function. If so, then this address is + * used by a multifunction device. + * + * Returns true if the address is being used by multiple devices, else + * false. + */ +bool +virDomainPCIAddressIsMulti(const virDomainDef *def, + virPCIDeviceAddressPtr addr) +{ + virDomainPCIAddressIsMultiIterData data = { .addr = addr, + .isMulti = false }; + + ignore_value(virDomainDeviceInfoIterate((virDomainDefPtr)def, + virDomainPCIAddressIsMultiIter, + &data)); + return data.isMulti; +} + + static char* virDomainCCWAddressAsString(virDomainDeviceCCWAddressPtr addr) { diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 9c08274..50c4675 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -173,6 +173,11 @@ int virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs, virDomainPCIConnectFlags flags) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +bool +virDomainPCIAddressIsMulti(const virDomainDef *def, + virPCIDeviceAddressPtr addr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + struct _virDomainCCWAddressSet { virHashTablePtr defined; virDomainDeviceCCWAddress next; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4c0170c..0dd0af5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -99,6 +99,7 @@ virDomainPCIAddressAsString; virDomainPCIAddressBusSetModel; virDomainPCIAddressEnsureAddr; virDomainPCIAddressFlagsCompatible; +virDomainPCIAddressIsMulti; virDomainPCIAddressReleaseSlot; virDomainPCIAddressReserveAddr; virDomainPCIAddressReserveNextAddr; -- 2.7.4

On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote:
This function iterates through all the devices in a domain to determine if the address it has been given is part of a "multifunction device" (i.e. multiple devices connected to different functions of the same slot).
[...]
+static int +virDomainPCIAddressIsMultiIter(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED, + virDomainDeviceInfoPtr info, + void *data) +{ + virDomainPCIAddressIsMultiIterData *context = data; + virPCIDeviceAddressPtr testAddr = context->addr;
s/testAddr/otherAddr/ Or not, up to you :) [...]
+/** + * virDomainPCIAddressIsMulti(): + * + * @def: the domain definition whose devices need adjusting + * @addr: the address to check + * + * See if there is any PCI device in the domain with the same + * domain/bus/slot but different function. If so, then this address is + * used by a multifunction device. + * + * Returns true if the address is being used by multiple devices, else + * false.
"false otherwise"?
+ */ +bool +virDomainPCIAddressIsMulti(const virDomainDef *def, + virPCIDeviceAddressPtr addr) +{ + virDomainPCIAddressIsMultiIterData data = { .addr = addr, + .isMulti = false }; + + ignore_value(virDomainDeviceInfoIterate((virDomainDefPtr)def,
Space between "(virDomainDefPtr)" and "def". ACK -- Andrea Bolognani / Red Hat / Virtualization

If the multifunction attribute isn't set in the config for the device at function 0 of a slot used for multifunction, it would previously have been an error. This patch will instead automatically correct the omission (but only if it hasn't been set at all - if someone explicitly has "multifunction='off'" on function 0, or "multifunction='on'" when function != 0, we have to assume they have a reason for that). This effectively obsoletes the requirement of specifying multifunction='on' in the config, although you're still free to do so. Note that if you migrate a domain that needs an implied "multifunction='on'" back to any older libvirt that doesn't have it, the migration will fail. (Note that this would only be an issue with a domain config that was *created* on a newer libvirt; any config created on an older libvirt and then later migrated to a newer libvirt would necessarily have multifunction explicitly set in the config, and that will not be lost during migration). --- src/qemu/qemu_command.c | 16 +++++- .../qemuxml2argv-q35-multifunction.args | 31 +++++++++++ .../qemuxml2argv-q35-multifunction.xml | 40 +++++++++++++ tests/qemuxml2argvtest.c | 23 ++++++++ .../qemuxml2xmlout-q35-multifunction.xml | 65 ++++++++++++++++++++++ tests/qemuxml2xmltest.c | 23 ++++++++ 6 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f8e48d2..c2e852e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -295,6 +295,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, int ret = -1; char *devStr = NULL; const char *contAlias = NULL; + virTristateSwitch multi = VIR_TRISTATE_SWITCH_ABSENT; if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { size_t i; @@ -327,6 +328,8 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, goto cleanup; } + multi = info->addr.pci.multi; + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) { if (info->addr.pci.function != 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -340,6 +343,15 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, "this QEMU binary")); goto cleanup; } + } else if (info->addr.pci.function == 0 && + multi == VIR_TRISTATE_SWITCH_ABSENT && + virDomainPCIAddressIsMulti(domainDef, &info->addr.pci)) { + /* Even if the config doesn't tell us, by definition we + * must have multifunction=on in the commandline for the + * device at function 0 if there are any other devices on + * the same slot. + */ + multi = VIR_TRISTATE_SWITCH_ON; } if (info->addr.pci.bus != 0 && @@ -351,9 +363,9 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, } virBufferAsprintf(buf, ",bus=%s", contAlias); - if (info->addr.pci.multi == VIR_TRISTATE_SWITCH_ON) + if (multi == VIR_TRISTATE_SWITCH_ON) virBufferAddLit(buf, ",multifunction=on"); - else if (info->addr.pci.multi == VIR_TRISTATE_SWITCH_OFF) + else if (multi == VIR_TRISTATE_SWITCH_OFF) virBufferAddLit(buf, ",multifunction=off"); virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot); if (info->addr.pci.function != 0) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args new file mode 100644 index 0000000..de1a4a4 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args @@ -0,0 +1,31 @@ +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 ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x18,chassis=4,id=pci.4,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=5,id=pci.5,bus=pcie.0,multifunction=on,\ +addr=0x3.0x1 \ +-device ioh3420,port=0x20,chassis=6,id=pci.6,bus=pcie.0,multifunction=off,\ +addr=0x4 \ +-device ioh3420,port=0x21,chassis=7,id=pci.7,bus=pcie.0,addr=0x4.0x1 \ +-device nec-usb-xhci,id=usb,bus=pci.1,addr=0x0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml new file mode 100644 index 0000000..b1f3c5e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml @@ -0,0 +1,40 @@ +<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='pcie-root-port'> + <address type='pci' slot='2' function='0'/> + </controller> + <controller type='pci' model='pcie-root-port'> + <address type='pci' slot='2' function='1'/> + </controller> + <controller type='pci' model='pcie-root-port'> + <address type='pci' slot='2' function='2'/> + </controller> + <controller type='pci' model='pcie-root-port'> + <address type='pci' slot='3' function='0'/> + </controller> + <controller type='pci' model='pcie-root-port'> + <address type='pci' slot='3' function='1' multifunction='on'/> + </controller> + <controller type='pci' model='pcie-root-port'> + <address type='pci' slot='4' function='0' multifunction='off'/> + </controller> + <controller type='pci' model='pcie-root-port'> + <address type='pci' slot='4' function='1'/> + </controller> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 81c62ac..c6f9593 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1916,6 +1916,29 @@ mymain(void) QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_NEC_USB_XHCI, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); + DO_TEST("q35-multifunction", + 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_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_NEC_USB_XHCI, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY); DO_TEST("q35-virt-manager-basic", QEMU_CAPS_KVM, QEMU_CAPS_RTC, diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml new file mode 100644 index 0000000..3d5cd76 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml @@ -0,0 +1,65 @@ +<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' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='1' port='0x10'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='2' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='3' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> + </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='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1' multifunction='on'/> + </controller> + <controller type='pci' index='6' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='6' port='0x20'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='off'/> + </controller> + <controller type='pci' index='7' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='7' port='0x21'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/> + </controller> + <controller type='usb' index='0' model='nec-xhci'> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index ddd17cb..569a375 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -795,6 +795,29 @@ mymain(void) QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_NEC_USB_XHCI, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); + DO_TEST("q35-multifunction", + 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_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_NEC_USB_XHCI, + QEMU_CAPS_DEVICE_VIDEO_PRIMARY); DO_TEST("q35-virt-manager-basic", QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY, QEMU_CAPS_DEVICE_VIRTIO_RNG, -- 2.7.4

On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote:
If the multifunction attribute isn't set in the config for the device at function 0 of a slot used for multifunction, it would previously have been an error. This patch will instead automatically correct the omission (but only if it hasn't been set at all - if someone explicitly has "multifunction='off'" on function 0, or "multifunction='on'" when function != 0, we have to assume they have a reason for that). This effectively obsoletes the requirement of specifying multifunction='on' in the config, although you're still free to do so. Note that if you migrate a domain that needs an implied "multifunction='on'" back to any older libvirt that doesn't have it, the migration will fail. (Note that this would only be an issue with a domain config that was *created* on a newer libvirt; any config created on an older libvirt and then later migrated to a newer libvirt would necessarily have multifunction explicitly set in the config, and that will not be lost during migration).
I keep forgetting our official stance on migrating to older libvirt versions... As far as I'm concerned, the only reason you would want to do that is because you are upgrading your hypervisor pool and, at some point during the process, you realize there are issues with the upgrade and need to roll back. As you mention, that use case would work just fine because the guests have been defined using an older libvirt versions. That said, is there any reason why this code can't be moved to the PostParse callback, so that the multifunction property will show up in the guest configuration and the issue will be side-stepped entirely? -- Andrea Bolognani / Red Hat / Virtualization

On Tue, Dec 20, 2016 at 04:19:35PM +0100, Andrea Bolognani wrote:
On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote:
If the multifunction attribute isn't set in the config for the device at function 0 of a slot used for multifunction, it would previously have been an error. This patch will instead automatically correct the omission (but only if it hasn't been set at all - if someone explicitly has "multifunction='off'" on function 0, or "multifunction='on'" when function != 0, we have to assume they have a reason for that). This effectively obsoletes the requirement of specifying multifunction='on' in the config, although you're still free to do so. Note that if you migrate a domain that needs an implied "multifunction='on'" back to any older libvirt that doesn't have it, the migration will fail. (Note that this would only be an issue with a domain config that was *created* on a newer libvirt; any config created on an older libvirt and then later migrated to a newer libvirt would necessarily have multifunction explicitly set in the config, and that will not be lost during migration).
I keep forgetting our official stance on migrating to older libvirt versions...
We need to be able to migrate new -> old, as apps like oVirt and OpenStack can be running a mix of old & new libvirt & QEMU versions and may migrate between the two in both directions.
As far as I'm concerned, the only reason you would want to do that is because you are upgrading your hypervisor pool and, at some point during the process, you realize there are issues with the upgrade and need to roll back. As you mention, that use case would work just fine because the guests have been defined using an older libvirt versions.
If you have 1000's of hypervisor nodes deployed, upgrading all of them may take a non-trivial amount of time (days, or even weeks). During this time you may need to use live migration and so the possible target host may be running new or old libvirt / QEMU - particularly during early stages of a rolling upgrade the majority of nodes will be old libvirt. Hence it is not uncommon to need to migrate old to new Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

On 12/20/2016 10:19 AM, Andrea Bolognani wrote:
If the multifunction attribute isn't set in the config for the device at function 0 of a slot used for multifunction, it would previously have been an error. This patch will instead automatically correct the omission (but only if it hasn't been set at all - if someone explicitly has "multifunction='off'" on function 0, or "multifunction='on'" when function != 0, we have to assume they have a reason for that).
This effectively obsoletes the requirement of specifying multifunction='on' in the config, although you're still free to do so. Note that if you migrate a domain that needs an implied "multifunction='on'" back to any older libvirt that doesn't have it, the migration will fail. (Note that this would only be an issue with a domain config that was *created* on a newer libvirt; any config created on an older libvirt and then later migrated to a newer libvirt would necessarily have multifunction explicitly set in the config, and that will not be lost during migration). I keep forgetting our official stance on migrating to older
On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote: libvirt versions...
As far as I'm concerned, the only reason you would want to do that is because you are upgrading your hypervisor pool and, at some point during the process, you realize there are issues with the upgrade and need to roll back. As you mention, that use case would work just fine because the guests have been defined using an older libvirt versions.
Thinking about it more - even if the domain is defined using a new libvirt version, as long as the management is still setting multifunction manually (which will be the case for everything except auto-added pcie-root-ports), it will still be reflected in the config, and a migration to a host with older libvirt will still work. This narrows the scope of "unable to migrate from new->old libvirt even more - it's only a problem if you define a new domain that auto-adds pcie-root-ports, or add pcie-root-ports to an existing domain on a "new libvirt" host, then migrate it to an "old libvirt" host. Since the auto-adding of pci-root-ports *at all* (much less on multiple functions of a single slot) is a new feature, and in general it's quite often not possible to migrate domains that use new features from newer to older libvirt, I think this is acceptable.
That said, is there any reason why this code can't be moved to the PostParse callback, so that the multifunction property will show up in the guest configuration and the issue will be side-stepped entirely?
I'd rather not pollute new configurations with attributes that aren't necessary. But more important - if you remove a device from a function of a slot and end up leaving only the device on function 0, then it should no longer have multifunction set; when we do the setting of multifunction automatically at runtime, this will happen by itself, but if we save the multifunction=on in the config, then it will require manual intervention. Normally I would say that it's desirable to record all option settings in the XML in order to maintain guest ABI, but in this case the existing setting would be incorrect once the other devices on the slot are removed, and the act of removing the other devices changes the guest ABI anyway, so it would/should be expected by the guest. So does this patch get an ACK? Or am I being too cavalier about migration compatibility?

On Mon, Dec 19, 2016 at 10:23:16AM -0500, Laine Stump wrote:
If the multifunction attribute isn't set in the config for the device at function 0 of a slot used for multifunction, it would previously have been an error. This patch will instead automatically correct the omission (but only if it hasn't been set at all - if someone explicitly has "multifunction='off'" on function 0, or "multifunction='on'" when function != 0, we have to assume they have a reason for that).
This effectively obsoletes the requirement of specifying multifunction='on' in the config, although you're still free to do so. Note that if you migrate a domain that needs an implied "multifunction='on'" back to any older libvirt that doesn't have it, the migration will fail. (Note that this would only be an issue with a domain config that was *created* on a newer libvirt; any config created on an older libvirt and then later migrated to a newer libvirt would necessarily have multifunction explicitly set in the config, and that will not be lost during migration).
So the reason we added multifunction=on as an explicit attribute is because it is an guest ABI change, even if function 0 is the only function present. commit c329db7180d77c8077b9f9cd167a71d7f347227a Author: Laine Stump <laine@laine.org> Date: Thu Sep 29 13:00:32 2011 -0400 qemu: make PCI multifunction support more manual When support for was added for PCI multifunction cards (in commit 9f8baf, first included in libvirt 0.9.3), it was done by always turning on the multifunction bit for all PCI devices. Since that time it has been realized that this is not an ideal solution, and that the multifunction bit must be selectively turned on. For example, see https://bugzilla.redhat.com/show_bug.cgi?id=728174 and the discussion before and after https://www.redhat.com/archives/libvir-list/2011-September/msg01036.html This patch modifies multifunction support so that the multifunction=on option is only added to the qemu commandline for a device if its PCI <address> definition has the attribute "multifunction='on'", e.g.: <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/> In practice, the multifunction bit should only be turned on if function='0' AND other functions will be used in the same slot - it usually isn't needed for functions 1-7 (although there are apparently some exceptions, e.g. the Intel X53 according to the QEMU source code), and should never be set if only function 0 will be used in the slot. The test cases have been changed accordingly to illustrate. With this patch in place, if a user attempts to assign multiple functions in a slot without setting the multifunction bit for function 0, libvirt will issue an error when the domain is defined, and the define operation will fail. In the future, we may decide to detect this situation and automatically add multifunction=on to avoid the error; even then it will still be useful to have a manual method of turning on multifunction since, as stated above, there are some devices that excpect it to be turned on for all functions in a slot. A side effect of this patch is that attempts to use the same PCI address for two different devices will now log an error (previously this would cause the domain define operation to fail, but there would be no log message generated). Because the function doing this log was almost completely rewritten, I didn't think it worthwhile to make a separate patch for that fix (the entire patch would immediately be obsoleted). You mentioned in your commit message there, that it would be a valid enhancement to automatically add multifunction=on, if-and-only-if we saw other devices with non-0 functions in the same slot. That all said, the concern I have is that although this change is not in itself an ABI incompatible change, it does mean that applications can accidentally trigger ABI incompatible changes in guests. For example, consider an app has defined a guest with 2 block devs in the same slot, but not set multifunction=on. Libvirt will silently set that attribute. Now the app re-defines the guest, but removes the second block device. libvirt will now not be setting multifunction=on on the 1st block device. So technically removing the second device has triggered a silent ABI change on the 1st device. IMHO, given that apps have to explicitly decide they're going to be using multifunction and thus manually assign addresses, it is no great burden for them to have to add multifunction=on explicitly too. IOW, I'd tend towards dropping this patch, as I don't think the benefit is compelling enough, and it can lead to surprises for apps. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

If a PCI device has VIR_PCI_CONNECT_AGGREGATE_SLOT set in its pciConnectFlags, then during address assignment we allow multiple instances of this type of device to be auto-assigned to multiple functions on the same device. A slot is used for aggregating multiple devices only if the first device assigned to that slot had VIR_PCI_CONNECT_AGGREGATE_SLOT set. but any device types that have AGGREGATE_SLOT set might be mix/matched on the same slot. (NB: libvirt should never set the AGGREGATE_SLOT flag for a device type that might need to be hotplugged. Currently it is only planned for pcie-root-port and possibly other PCI controller types, and none of those are hotpluggable anyway) There aren't yet any devices that use this flag. That will be in a later patch. --- src/conf/domain_addr.c | 45 +++++++++++++++++++++++++++++++++++++++--- src/conf/domain_addr.h | 30 +++++++++++++++++++--------- src/qemu/qemu_domain_address.c | 2 +- 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index b8a91d2..18421e0 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -564,8 +564,20 @@ virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, addrStr); goto cleanup; } + + /* if this is the first function to be reserved on this slot, and + * the device it's being reserved for can aggregate multiples on a + * slot, set the slot's aggregate flag. + */ + if (!bus->slot[addr->slot].functions && + flags & VIR_PCI_CONNECT_AGGREGATE_SLOT) { + bus->slot[addr->slot].aggregate = true; + } + + /* mark the requested function as reserved */ bus->slot[addr->slot].functions |= (1 << addr->function); - VIR_DEBUG("Reserving PCI address %s", addrStr); + VIR_DEBUG("Reserving PCI address %s (aggregate='%s')", addrStr, + bus->slot[addr->slot].aggregate ? "true" : "false"); ret = 0; cleanup: @@ -694,7 +706,7 @@ virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs) static int virDomainPCIAddressFindUnusedFunctionOnBus(virDomainPCIAddressBusPtr bus, virPCIDeviceAddressPtr searchAddr, - int function ATTRIBUTE_UNUSED, + int function, virDomainPCIConnectFlags flags, bool *found) { @@ -717,6 +729,33 @@ virDomainPCIAddressFindUnusedFunctionOnBus(virDomainPCIAddressBusPtr bus, break; } + if (flags & VIR_PCI_CONNECT_AGGREGATE_SLOT && + bus->slot[searchAddr->slot].aggregate) { + /* slot and device are okay with aggregating devices */ + if ((bus->slot[searchAddr->slot].functions & + (1 << searchAddr->function)) == 0) { + *found = true; + break; + } + + /* also check for *any* unused function if caller + * sent function = -1 + */ + if (function == -1) { + while (searchAddr->function < 8) { + if ((bus->slot[searchAddr->slot].functions & + (1 << searchAddr->function)) == 0) { + *found = true; + break; /* out of inner while */ + } + searchAddr->function++; + } + if (*found) + break; /* out of outer while */ + searchAddr->function = 0; /* reset for next try */ + } + } + VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use", searchAddr->domain, searchAddr->bus, searchAddr->slot); searchAddr->slot++; @@ -863,7 +902,7 @@ virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev, virDomainPCIConnectFlags flags) { - return virDomainPCIAddressReserveNextAddr(addrs, dev, flags, 0); + return virDomainPCIAddressReserveNextAddr(addrs, dev, flags, -1); } diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 50c4675..dd4cd5b 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -32,18 +32,23 @@ typedef enum { VIR_PCI_CONNECT_HOTPLUGGABLE = 1 << 0, /* is hotplug needed/supported */ + /* set for devices that can share a single slot in auto-assignment + * (by assigning one device to each of the 8 functions on the slot) + */ + VIR_PCI_CONNECT_AGGREGATE_SLOT = 1 << 1, + /* kinds of devices as a bitmap so they can be combined (some PCI * controllers permit connecting multiple types of devices) */ - VIR_PCI_CONNECT_TYPE_PCI_DEVICE = 1 << 1, - VIR_PCI_CONNECT_TYPE_PCIE_DEVICE = 1 << 2, - VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT = 1 << 3, - VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT = 1 << 4, - VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT = 1 << 5, - 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, + VIR_PCI_CONNECT_TYPE_PCI_DEVICE = 1 << 2, + VIR_PCI_CONNECT_TYPE_PCIE_DEVICE = 1 << 3, + VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT = 1 << 4, + VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT = 1 << 5, + VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT = 1 << 6, + VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE = 1 << 7, + VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS = 1 << 8, + VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS = 1 << 9, + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE = 1 << 10, } virDomainPCIConnectFlags; /* a combination of all bits that describe the type of connections @@ -75,6 +80,13 @@ typedef struct { * in use by a device, or clear if it isn't. */ uint8_t functions; + + /* aggregate is true if this slot has only devices with + * VIR_PCI_CONNECT_AGGREGATE assigned to its functions (meaning + * that other devices with the same flags could also be + * auto-assigned to the other functions) + */ + bool aggregate; } virDomainPCIAddressSlot; typedef struct { diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 4a2a489..8e2ffe0 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -904,7 +904,7 @@ static int qemuDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs, virDomainDeviceInfoPtr dev) { - return qemuDomainPCIAddressReserveNextAddr(addrs, dev, 0); + return qemuDomainPCIAddressReserveNextAddr(addrs, dev, -1); } -- 2.7.4

On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote:
If a PCI device has VIR_PCI_CONNECT_AGGREGATE_SLOT set in its pciConnectFlags, then during address assignment we allow multiple instances of this type of device to be auto-assigned to multiple functions on the same device. A slot is used for aggregating multiple devices only if the first device assigned to that slot had VIR_PCI_CONNECT_AGGREGATE_SLOT set. but any device types that have AGGREGATE_SLOT set might be mix/matched on the same slot.
[...]
@@ -717,6 +729,33 @@ virDomainPCIAddressFindUnusedFunctionOnBus(virDomainPCIAddressBusPtr bus, break; } + if (flags & VIR_PCI_CONNECT_AGGREGATE_SLOT && + bus->slot[searchAddr->slot].aggregate) { + /* slot and device are okay with aggregating devices */ + if ((bus->slot[searchAddr->slot].functions & + (1 << searchAddr->function)) == 0) { + *found = true; + break; + } + + /* also check for *any* unused function if caller + * sent function = -1 + */ + if (function == -1) { + while (searchAddr->function < 8) {
We know this works because virDomainPCIAddressGetNextSlot() will set 'searchAddr->function = 0' when 'function == -1', but I'd rather see...
+ if ((bus->slot[searchAddr->slot].functions & + (1 << searchAddr->function)) == 0) { + *found = true; + break; /* out of inner while */ + } + searchAddr->function++; + } + if (*found) + break; /* out of outer while */ + searchAddr->function = 0; /* reset for next try */
... this line moved right before the while() loop to get rid of that dependency entirely. ACK with that changed. -- Andrea Bolognani / Red Hat / Virtualization

Set the VIR_PCI_CONNECT_AGGREGATE_SLOT flag for pcie-root-ports so that they will be assigned to all the functions on a slot. Some qemu test case outputs had to be adjusted due to the pcie-root-ports now being put on multiple functions. --- src/conf/domain_addr.c | 2 +- .../qemuxml2argv-pcie-root-port.args | 5 +- .../qemuxml2argv-pcie-switch-upstream-port.args | 5 +- .../qemuxml2argv-q35-default-devices-only.args | 7 +-- .../qemuxml2argv-q35-multifunction.args | 12 +++++ .../qemuxml2argv-q35-multifunction.xml | 11 +++++ .../qemuxml2argv-q35-pcie-autoadd.args | 30 ++++++------ tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 28 ++++++----- .../qemuxml2argv-q35-virt-manager-basic.args | 13 ++--- .../qemuxml2argv-q35-virtio-pci.args | 28 ++++++----- tests/qemuxml2argvtest.c | 2 + .../qemuxml2xmlout-pcie-root-port.xml | 2 +- .../qemuxml2xmlout-pcie-switch-upstream-port.xml | 4 +- .../qemuxml2xmlout-q35-default-devices-only.xml | 8 ++-- .../qemuxml2xmlout-q35-multifunction.xml | 55 ++++++++++++++++++++++ .../qemuxml2xmlout-q35-pcie-autoadd.xml | 52 ++++++++++---------- .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 48 +++++++++---------- .../qemuxml2xmlout-q35-virt-manager-basic.xml | 20 ++++---- .../qemuxml2xmlout-q35-virtio-pci.xml | 48 +++++++++---------- tests/qemuxml2xmltest.c | 2 + 20 files changed, 237 insertions(+), 145 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 18421e0..d60b1d9 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -63,7 +63,7 @@ virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) return VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: - return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT; + return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT | VIR_PCI_CONNECT_AGGREGATE_SLOT; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: return VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args index 27d5164..9a71281 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args @@ -18,8 +18,9 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x1a,chassis=40,id=pci.4,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x1a,chassis=40,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \ -device ide-drive,bus=ide.0,drive=drive-sata0-0-0,id=sata0-0-0 \ -device qxl-vga,id=video0,ram_size=67108864,vram_size=33554432,bus=pcie.0,\ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args b/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args index 93d16b8..10aedd5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args @@ -18,8 +18,9 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=4,id=pci.4,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ -device x3130-upstream,id=pci.5,bus=pci.3,addr=0x0 \ -device x3130-upstream,id=pci.6,bus=pci.4,addr=0x0 \ -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args index 9d13466..30fc9b7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args @@ -16,8 +16,9 @@ QEMU_AUDIO_DRV=none \ -monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \ -no-acpi \ -boot c \ --device ioh3420,port=0x8,chassis=1,id=pci.1,bus=pcie.0,addr=0x1 \ --device ioh3420,port=0x10,chassis=2,id=pci.2,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=3,id=pci.3,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x1 \ +-device ioh3420,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ +-device ioh3420,port=0xa,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \ -device nec-usb-xhci,id=usb,bus=pci.1,addr=0x0 \ -device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args index de1a4a4..1b60744 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args @@ -27,5 +27,17 @@ addr=0x3.0x1 \ -device ioh3420,port=0x20,chassis=6,id=pci.6,bus=pcie.0,multifunction=off,\ addr=0x4 \ -device ioh3420,port=0x21,chassis=7,id=pci.7,bus=pcie.0,addr=0x4.0x1 \ +-device ioh3420,port=0x8,chassis=8,id=pci.8,bus=pcie.0,multifunction=on,\ +addr=0x1 \ +-device ioh3420,port=0x9,chassis=9,id=pci.9,bus=pcie.0,addr=0x1.0x1 \ +-device ioh3420,port=0xa,chassis=10,id=pci.10,bus=pcie.0,addr=0x1.0x2 \ +-device ioh3420,port=0xb,chassis=11,id=pci.11,bus=pcie.0,addr=0x1.0x3 \ +-device ioh3420,port=0xc,chassis=12,id=pci.12,bus=pcie.0,addr=0x1.0x4 \ +-device ioh3420,port=0xd,chassis=13,id=pci.13,bus=pcie.0,addr=0x1.0x5 \ +-device ioh3420,port=0xe,chassis=14,id=pci.14,bus=pcie.0,addr=0x1.0x6 \ +-device ioh3420,port=0xf,chassis=15,id=pci.15,bus=pcie.0,addr=0x1.0x7 \ +-device ioh3420,port=0x13,chassis=16,id=pci.16,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=17,id=pci.17,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=18,id=pci.18,bus=pcie.0,addr=0x2.0x5 \ -device nec-usb-xhci,id=usb,bus=pci.1,addr=0x0 \ -device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml index b1f3c5e..c1edca1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml @@ -36,5 +36,16 @@ <controller type='pci' model='pcie-root-port'> <address type='pci' slot='4' function='1'/> </controller> + <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'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args index ba26326..f3d44c0 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args @@ -16,20 +16,22 @@ QEMU_AUDIO_DRV=none \ -monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \ -no-acpi \ -boot c \ --device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=2,id=pci.2,bus=pcie.0,addr=0x3 \ --device ioh3420,port=0x20,chassis=3,id=pci.3,bus=pcie.0,addr=0x4 \ --device ioh3420,port=0x28,chassis=4,id=pci.4,bus=pcie.0,addr=0x5 \ --device ioh3420,port=0x30,chassis=5,id=pci.5,bus=pcie.0,addr=0x6 \ --device ioh3420,port=0x38,chassis=6,id=pci.6,bus=pcie.0,addr=0x7 \ --device ioh3420,port=0x40,chassis=7,id=pci.7,bus=pcie.0,addr=0x8 \ --device ioh3420,port=0x48,chassis=8,id=pci.8,bus=pcie.0,addr=0x9 \ --device ioh3420,port=0x50,chassis=9,id=pci.9,bus=pcie.0,addr=0xa \ --device ioh3420,port=0x58,chassis=10,id=pci.10,bus=pcie.0,addr=0xb \ --device ioh3420,port=0x60,chassis=11,id=pci.11,bus=pcie.0,addr=0xc \ --device ioh3420,port=0x68,chassis=12,id=pci.12,bus=pcie.0,addr=0xd \ --device ioh3420,port=0x70,chassis=13,id=pci.13,bus=pcie.0,addr=0xe \ --device ioh3420,port=0x78,chassis=14,id=pci.14,bus=pcie.0,addr=0xf \ +-device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x5 \ +-device ioh3420,port=0x16,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x6 \ +-device ioh3420,port=0x17,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x7 \ +-device ioh3420,port=0x18,chassis=9,id=pci.9,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=10,id=pci.10,bus=pcie.0,addr=0x3.0x1 \ +-device ioh3420,port=0x1a,chassis=11,id=pci.11,bus=pcie.0,addr=0x3.0x2 \ +-device ioh3420,port=0x1b,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x3 \ +-device ioh3420,port=0x1c,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x4 \ +-device ioh3420,port=0x1d,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x5 \ -device nec-usb-xhci,id=usb,bus=pci.6,addr=0x0 \ -device virtio-scsi-pci,id=scsi0,bus=pci.5,addr=0x0 \ -device virtio-serial-pci,id=virtio-serial0,bus=pci.4,addr=0x0 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args index 2738749..3b507f3 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args @@ -18,19 +18,21 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device 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 ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ --device ioh3420,port=0x70,chassis=15,id=pci.15,bus=pcie.0,addr=0xe \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x5 \ +-device ioh3420,port=0x16,chassis=9,id=pci.9,bus=pcie.0,addr=0x2.0x6 \ +-device ioh3420,port=0x17,chassis=10,id=pci.10,bus=pcie.0,addr=0x2.0x7 \ +-device ioh3420,port=0x18,chassis=11,id=pci.11,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x1 \ +-device ioh3420,port=0x1a,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x2 \ +-device ioh3420,port=0x1b,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x3 \ +-device ioh3420,port=0x1c,chassis=15,id=pci.15,bus=pcie.0,addr=0x3.0x4 \ -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 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args index 60af251..e139e52 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args @@ -18,12 +18,13 @@ QEMU_AUDIO_DRV=spice \ -global ICH9-LPC.disable_s3=1 \ -global ICH9-LPC.disable_s4=1 \ -boot c \ --device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=2,id=pci.2,bus=pcie.0,addr=0x3 \ --device ioh3420,port=0x20,chassis=3,id=pci.3,bus=pcie.0,addr=0x4 \ --device ioh3420,port=0x28,chassis=4,id=pci.4,bus=pcie.0,addr=0x5 \ --device ioh3420,port=0x30,chassis=5,id=pci.5,bus=pcie.0,addr=0x6 \ --device ioh3420,port=0x38,chassis=6,id=pci.6,bus=pcie.0,addr=0x7 \ +-device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x5 \ -device nec-usb-xhci,id=usb,bus=pci.2,addr=0x0 \ -device virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 \ -drive file=/var/lib/libvirt/images/basic.qcow2,format=qcow2,if=none,\ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args index cada05e..a1025dc 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args @@ -18,19 +18,21 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device 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 ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ --device ioh3420,port=0x70,chassis=15,id=pci.15,bus=pcie.0,addr=0xe \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x5 \ +-device ioh3420,port=0x16,chassis=9,id=pci.9,bus=pcie.0,addr=0x2.0x6 \ +-device ioh3420,port=0x17,chassis=10,id=pci.10,bus=pcie.0,addr=0x2.0x7 \ +-device ioh3420,port=0x18,chassis=11,id=pci.11,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x1 \ +-device ioh3420,port=0x1a,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x2 \ +-device ioh3420,port=0x1b,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x3 \ +-device ioh3420,port=0x1c,chassis=15,id=pci.15,bus=pcie.0,addr=0x3.0x4 \ -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 \ diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c6f9593..becb492 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1978,6 +1978,7 @@ mymain(void) QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_ICH9_AHCI, + QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("autoindex", @@ -2021,6 +2022,7 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_DEVICE_X3130_UPSTREAM, QEMU_CAPS_ICH9_AHCI, + QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("pcie-switch-downstream-port", diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml index a4ff820..082dd6c 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml @@ -37,7 +37,7 @@ <controller type='pci' index='4' model='pcie-root-port'> <model name='ioh3420'/> <target chassis='40' port='0x1a'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='sata' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml index 53e10d0..52c9177 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml @@ -36,8 +36,8 @@ </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'/> + <target chassis='4' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='pci' index='5' model='pcie-switch-upstream-port'> <model name='x3130-upstream'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml index e64b80c..e8a7d8c 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml @@ -28,13 +28,13 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x10'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + <target chassis='2' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> </controller> <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='3' port='0x18'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <target chassis='3' port='0xa'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml index 3d5cd76..06b8144 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml @@ -50,6 +50,61 @@ <target chassis='7' port='0x21'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/> </controller> + <controller type='pci' index='8' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='8' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='pci' index='9' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='9' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='10' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='10' port='0xa'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='11' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='11' port='0xb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/> + </controller> + <controller type='pci' index='12' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='12' port='0xc'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/> + </controller> + <controller type='pci' index='13' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='13' port='0xd'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x5'/> + </controller> + <controller type='pci' index='14' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='14' port='0xe'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x6'/> + </controller> + <controller type='pci' index='15' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='15' port='0xf'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x7'/> + </controller> + <controller type='pci' index='16' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='16' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> + </controller> + <controller type='pci' index='17' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='17' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> + </controller> + <controller type='pci' index='18' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='18' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> + </controller> <controller type='usb' index='0' model='nec-xhci'> <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </controller> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml index 3742e14..28862c9 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml @@ -39,68 +39,68 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x18'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <target chassis='2' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='3' port='0x20'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + <target chassis='3' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </controller> <controller type='pci' index='4' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='4' port='0x28'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + <target chassis='4' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </controller> <controller type='pci' index='5' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='5' port='0x30'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + <target chassis='5' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </controller> <controller type='pci' index='6' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='6' port='0x38'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + <target chassis='6' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </controller> <controller type='pci' index='7' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='7' port='0x40'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> + <target chassis='7' port='0x16'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/> </controller> <controller type='pci' index='8' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='8' port='0x48'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + <target chassis='8' port='0x17'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/> </controller> <controller type='pci' index='9' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='9' port='0x50'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + <target chassis='9' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </controller> <controller type='pci' index='10' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='10' port='0x58'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + <target chassis='10' port='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </controller> <controller type='pci' index='11' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='11' port='0x60'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> + <target chassis='11' port='0x1a'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/> </controller> <controller type='pci' index='12' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='12' port='0x68'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/> + <target chassis='12' port='0x1b'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/> </controller> <controller type='pci' index='13' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='13' port='0x70'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0e' function='0x0'/> + <target chassis='13' port='0x1c'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/> </controller> <controller type='pci' index='14' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='14' port='0x78'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0f' function='0x0'/> + <target chassis='14' port='0x1d'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/> </controller> <filesystem type='mount' accessmode='passthrough'> <source dir='/export/to/guest'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml index 8e727fb..7c74b60 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml @@ -36,63 +36,63 @@ </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'/> + <target chassis='4' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </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'/> + <target chassis='5' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </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'/> + <target chassis='6' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </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'/> + <target chassis='7' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </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'/> + <target chassis='8' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </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'/> + <target chassis='9' port='0x16'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/> </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'/> + <target chassis='10' port='0x17'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/> </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'/> + <target chassis='11' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' 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'/> + <target chassis='12' port='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </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'/> + <target chassis='13' port='0x1a'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/> </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'/> + <target chassis='14' port='0x1b'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/> </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'/> + <target chassis='15' port='0x1c'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/> </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml index 236d955..3bbd99f 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml @@ -50,28 +50,28 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x18'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <target chassis='2' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='3' port='0x20'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + <target chassis='3' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </controller> <controller type='pci' index='4' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='4' port='0x28'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + <target chassis='4' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </controller> <controller type='pci' index='5' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='5' port='0x30'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + <target chassis='5' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </controller> <controller type='pci' index='6' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='6' port='0x38'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + <target chassis='6' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </controller> <interface type='user'> <mac address='52:54:00:9a:e6:c6'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml index c4bd357..d2fa885 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml @@ -36,63 +36,63 @@ </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'/> + <target chassis='4' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </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'/> + <target chassis='5' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </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'/> + <target chassis='6' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </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'/> + <target chassis='7' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </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'/> + <target chassis='8' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </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'/> + <target chassis='9' port='0x16'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/> </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'/> + <target chassis='10' port='0x17'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/> </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'/> + <target chassis='11' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' 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'/> + <target chassis='12' port='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </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'/> + <target chassis='13' port='0x1a'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/> </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'/> + <target chassis='14' port='0x1b'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/> </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'/> + <target chassis='15' port='0x1c'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/> </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0'/> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 569a375..845e935 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -850,11 +850,13 @@ mymain(void) DO_TEST("pcie-root-port", 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_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("pcie-switch-upstream-port", 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_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("pcie-switch-downstream-port", -- 2.7.4

On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote:
Set the VIR_PCI_CONNECT_AGGREGATE_SLOT flag for pcie-root-ports so that they will be assigned to all the functions on a slot. Some qemu test case outputs had to be adjusted due to the pcie-root-ports now being put on multiple functions.
I noticed most of the pcie-root-ports get a new value for the port attribute after the change, while the chassis attribute remains always the same AFAICT. I just thought I'd point it out, but I assume you were already aware of it and it's not an issue, in which case ACK -- Andrea Bolognani / Red Hat / Virtualization

On 12/20/2016 12:50 PM, Andrea Bolognani wrote:
Set the VIR_PCI_CONNECT_AGGREGATE_SLOT flag for pcie-root-ports so that they will be assigned to all the functions on a slot.
Some qemu test case outputs had to be adjusted due to the pcie-root-ports now being put on multiple functions. I noticed most of the pcie-root-ports get a new value for the
On Mon, 2016-12-19 at 10:23 -0500, Laine Stump wrote: port attribute after the change, while the chassis attribute remains always the same AFAICT.
That's because the chassis attribute is just set to the index of the controller, while port is set to slot<<3 + function (this was recommended by some PCI person, Alex I think). I believe chassis needs to be unique within the entire machine, while port needs to be unique only for the bus that the controller is connected to.
I just thought I'd point it out, but I assume you were already aware of it and it's not an issue, in which case
ACK
-- Andrea Bolognani / Red Hat / Virtualization

On Fri, 2017-01-06 at 09:53 -0500, Laine Stump wrote:
I noticed most of the pcie-root-ports get a new value for the port attribute after the change, while the chassis attribute remains always the same AFAICT. That's because the chassis attribute is just set to the index of the controller, while port is set to slot<<3 + function (this was recommended by some PCI person, Alex I think). I believe chassis needs to be unique within the entire machine, while port needs to be unique only for the bus that the controller is connected to.
Again, I don't think this is a problem at all, but it would be nice to get a confirmation the attributes are indeed being used properly. Is their meaning documented anywhere? -- Andrea Bolognani / Red Hat / Virtualization

On 12/19/2016 10:23 AM, Laine Stump wrote:
Set the VIR_PCI_CONNECT_AGGREGATE_SLOT flag for pcie-root-ports so that they will be assigned to all the functions on a slot.
Some qemu test case outputs had to be adjusted due to the pcie-root-ports now being put on multiple functions. ---
ARGH! In my final rebase before pushing, I pulled in Andrea's patches that switch aarch64/virt to using PCI by default, and the test case for that resulted in a make check failure: 564) QEMU XML-2-ARGV aarch64-virtio-pci-default ... libvirt: QEMU Driver error : unsupported configuration: 'multifunction=on' is not supported with this QEMU binary FAILED Is it really true that the aarch64 qemu doesn't support multifunction devices? If so, that really needs to be fixed. In the meantime, this means I still can't push my patches, because doing so will break aarch64. I'll try to come up with a patch to conditionalize AGGREGATE_SLOT on support for multifunction (which I suppose I should have done to begin with, but I wouldn't have expected that a platform that supports PCIe doesn't support multifunction devices :-/)
src/conf/domain_addr.c | 2 +- .../qemuxml2argv-pcie-root-port.args | 5 +- .../qemuxml2argv-pcie-switch-upstream-port.args | 5 +- .../qemuxml2argv-q35-default-devices-only.args | 7 +-- .../qemuxml2argv-q35-multifunction.args | 12 +++++ .../qemuxml2argv-q35-multifunction.xml | 11 +++++ .../qemuxml2argv-q35-pcie-autoadd.args | 30 ++++++------ tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 28 ++++++----- .../qemuxml2argv-q35-virt-manager-basic.args | 13 ++--- .../qemuxml2argv-q35-virtio-pci.args | 28 ++++++----- tests/qemuxml2argvtest.c | 2 + .../qemuxml2xmlout-pcie-root-port.xml | 2 +- .../qemuxml2xmlout-pcie-switch-upstream-port.xml | 4 +- .../qemuxml2xmlout-q35-default-devices-only.xml | 8 ++-- .../qemuxml2xmlout-q35-multifunction.xml | 55 ++++++++++++++++++++++ .../qemuxml2xmlout-q35-pcie-autoadd.xml | 52 ++++++++++---------- .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 48 +++++++++---------- .../qemuxml2xmlout-q35-virt-manager-basic.xml | 20 ++++---- .../qemuxml2xmlout-q35-virtio-pci.xml | 48 +++++++++---------- tests/qemuxml2xmltest.c | 2 + 20 files changed, 237 insertions(+), 145 deletions(-)
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 18421e0..d60b1d9 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -63,7 +63,7 @@ virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) return VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE;
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: - return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT; + return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT | VIR_PCI_CONNECT_AGGREGATE_SLOT;
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: return VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args index 27d5164..9a71281 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args @@ -18,8 +18,9 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x1a,chassis=40,id=pci.4,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x1a,chassis=40,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \ -device ide-drive,bus=ide.0,drive=drive-sata0-0-0,id=sata0-0-0 \ -device qxl-vga,id=video0,ram_size=67108864,vram_size=33554432,bus=pcie.0,\ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args b/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args index 93d16b8..10aedd5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args @@ -18,8 +18,9 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=4,id=pci.4,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ -device x3130-upstream,id=pci.5,bus=pci.3,addr=0x0 \ -device x3130-upstream,id=pci.6,bus=pci.4,addr=0x0 \ -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args index 9d13466..30fc9b7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args @@ -16,8 +16,9 @@ QEMU_AUDIO_DRV=none \ -monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \ -no-acpi \ -boot c \ --device ioh3420,port=0x8,chassis=1,id=pci.1,bus=pcie.0,addr=0x1 \ --device ioh3420,port=0x10,chassis=2,id=pci.2,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=3,id=pci.3,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x1 \ +-device ioh3420,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ +-device ioh3420,port=0xa,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \ -device nec-usb-xhci,id=usb,bus=pci.1,addr=0x0 \ -device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args index de1a4a4..1b60744 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args @@ -27,5 +27,17 @@ addr=0x3.0x1 \ -device ioh3420,port=0x20,chassis=6,id=pci.6,bus=pcie.0,multifunction=off,\ addr=0x4 \ -device ioh3420,port=0x21,chassis=7,id=pci.7,bus=pcie.0,addr=0x4.0x1 \ +-device ioh3420,port=0x8,chassis=8,id=pci.8,bus=pcie.0,multifunction=on,\ +addr=0x1 \ +-device ioh3420,port=0x9,chassis=9,id=pci.9,bus=pcie.0,addr=0x1.0x1 \ +-device ioh3420,port=0xa,chassis=10,id=pci.10,bus=pcie.0,addr=0x1.0x2 \ +-device ioh3420,port=0xb,chassis=11,id=pci.11,bus=pcie.0,addr=0x1.0x3 \ +-device ioh3420,port=0xc,chassis=12,id=pci.12,bus=pcie.0,addr=0x1.0x4 \ +-device ioh3420,port=0xd,chassis=13,id=pci.13,bus=pcie.0,addr=0x1.0x5 \ +-device ioh3420,port=0xe,chassis=14,id=pci.14,bus=pcie.0,addr=0x1.0x6 \ +-device ioh3420,port=0xf,chassis=15,id=pci.15,bus=pcie.0,addr=0x1.0x7 \ +-device ioh3420,port=0x13,chassis=16,id=pci.16,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=17,id=pci.17,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=18,id=pci.18,bus=pcie.0,addr=0x2.0x5 \ -device nec-usb-xhci,id=usb,bus=pci.1,addr=0x0 \ -device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml index b1f3c5e..c1edca1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml @@ -36,5 +36,16 @@ <controller type='pci' model='pcie-root-port'> <address type='pci' slot='4' function='1'/> </controller> + <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'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args index ba26326..f3d44c0 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args @@ -16,20 +16,22 @@ QEMU_AUDIO_DRV=none \ -monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \ -no-acpi \ -boot c \ --device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=2,id=pci.2,bus=pcie.0,addr=0x3 \ --device ioh3420,port=0x20,chassis=3,id=pci.3,bus=pcie.0,addr=0x4 \ --device ioh3420,port=0x28,chassis=4,id=pci.4,bus=pcie.0,addr=0x5 \ --device ioh3420,port=0x30,chassis=5,id=pci.5,bus=pcie.0,addr=0x6 \ --device ioh3420,port=0x38,chassis=6,id=pci.6,bus=pcie.0,addr=0x7 \ --device ioh3420,port=0x40,chassis=7,id=pci.7,bus=pcie.0,addr=0x8 \ --device ioh3420,port=0x48,chassis=8,id=pci.8,bus=pcie.0,addr=0x9 \ --device ioh3420,port=0x50,chassis=9,id=pci.9,bus=pcie.0,addr=0xa \ --device ioh3420,port=0x58,chassis=10,id=pci.10,bus=pcie.0,addr=0xb \ --device ioh3420,port=0x60,chassis=11,id=pci.11,bus=pcie.0,addr=0xc \ --device ioh3420,port=0x68,chassis=12,id=pci.12,bus=pcie.0,addr=0xd \ --device ioh3420,port=0x70,chassis=13,id=pci.13,bus=pcie.0,addr=0xe \ --device ioh3420,port=0x78,chassis=14,id=pci.14,bus=pcie.0,addr=0xf \ +-device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x5 \ +-device ioh3420,port=0x16,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x6 \ +-device ioh3420,port=0x17,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x7 \ +-device ioh3420,port=0x18,chassis=9,id=pci.9,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=10,id=pci.10,bus=pcie.0,addr=0x3.0x1 \ +-device ioh3420,port=0x1a,chassis=11,id=pci.11,bus=pcie.0,addr=0x3.0x2 \ +-device ioh3420,port=0x1b,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x3 \ +-device ioh3420,port=0x1c,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x4 \ +-device ioh3420,port=0x1d,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x5 \ -device nec-usb-xhci,id=usb,bus=pci.6,addr=0x0 \ -device virtio-scsi-pci,id=scsi0,bus=pci.5,addr=0x0 \ -device virtio-serial-pci,id=virtio-serial0,bus=pci.4,addr=0x0 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args index 2738749..3b507f3 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args @@ -18,19 +18,21 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device 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 ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ --device ioh3420,port=0x70,chassis=15,id=pci.15,bus=pcie.0,addr=0xe \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x5 \ +-device ioh3420,port=0x16,chassis=9,id=pci.9,bus=pcie.0,addr=0x2.0x6 \ +-device ioh3420,port=0x17,chassis=10,id=pci.10,bus=pcie.0,addr=0x2.0x7 \ +-device ioh3420,port=0x18,chassis=11,id=pci.11,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x1 \ +-device ioh3420,port=0x1a,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x2 \ +-device ioh3420,port=0x1b,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x3 \ +-device ioh3420,port=0x1c,chassis=15,id=pci.15,bus=pcie.0,addr=0x3.0x4 \ -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 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args index 60af251..e139e52 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args @@ -18,12 +18,13 @@ QEMU_AUDIO_DRV=spice \ -global ICH9-LPC.disable_s3=1 \ -global ICH9-LPC.disable_s4=1 \ -boot c \ --device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=2,id=pci.2,bus=pcie.0,addr=0x3 \ --device ioh3420,port=0x20,chassis=3,id=pci.3,bus=pcie.0,addr=0x4 \ --device ioh3420,port=0x28,chassis=4,id=pci.4,bus=pcie.0,addr=0x5 \ --device ioh3420,port=0x30,chassis=5,id=pci.5,bus=pcie.0,addr=0x6 \ --device ioh3420,port=0x38,chassis=6,id=pci.6,bus=pcie.0,addr=0x7 \ +-device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x5 \ -device nec-usb-xhci,id=usb,bus=pci.2,addr=0x0 \ -device virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 \ -drive file=/var/lib/libvirt/images/basic.qcow2,format=qcow2,if=none,\ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args index cada05e..a1025dc 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args @@ -18,19 +18,21 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device 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 ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ --device ioh3420,port=0x70,chassis=15,id=pci.15,bus=pcie.0,addr=0xe \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x5 \ +-device ioh3420,port=0x16,chassis=9,id=pci.9,bus=pcie.0,addr=0x2.0x6 \ +-device ioh3420,port=0x17,chassis=10,id=pci.10,bus=pcie.0,addr=0x2.0x7 \ +-device ioh3420,port=0x18,chassis=11,id=pci.11,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x1 \ +-device ioh3420,port=0x1a,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x2 \ +-device ioh3420,port=0x1b,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x3 \ +-device ioh3420,port=0x1c,chassis=15,id=pci.15,bus=pcie.0,addr=0x3.0x4 \ -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 \ diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c6f9593..becb492 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1978,6 +1978,7 @@ mymain(void) QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_ICH9_AHCI, + QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("autoindex", @@ -2021,6 +2022,7 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_DEVICE_X3130_UPSTREAM, QEMU_CAPS_ICH9_AHCI, + QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("pcie-switch-downstream-port", diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml index a4ff820..082dd6c 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml @@ -37,7 +37,7 @@ <controller type='pci' index='4' model='pcie-root-port'> <model name='ioh3420'/> <target chassis='40' port='0x1a'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='sata' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml index 53e10d0..52c9177 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml @@ -36,8 +36,8 @@ </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'/> + <target chassis='4' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='pci' index='5' model='pcie-switch-upstream-port'> <model name='x3130-upstream'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml index e64b80c..e8a7d8c 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml @@ -28,13 +28,13 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x10'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + <target chassis='2' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> </controller> <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='3' port='0x18'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <target chassis='3' port='0xa'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml index 3d5cd76..06b8144 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml @@ -50,6 +50,61 @@ <target chassis='7' port='0x21'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/> </controller> + <controller type='pci' index='8' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='8' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='pci' index='9' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='9' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='10' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='10' port='0xa'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='11' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='11' port='0xb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/> + </controller> + <controller type='pci' index='12' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='12' port='0xc'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/> + </controller> + <controller type='pci' index='13' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='13' port='0xd'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x5'/> + </controller> + <controller type='pci' index='14' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='14' port='0xe'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x6'/> + </controller> + <controller type='pci' index='15' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='15' port='0xf'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x7'/> + </controller> + <controller type='pci' index='16' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='16' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> + </controller> + <controller type='pci' index='17' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='17' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> + </controller> + <controller type='pci' index='18' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='18' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> + </controller> <controller type='usb' index='0' model='nec-xhci'> <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </controller> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml index 3742e14..28862c9 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml @@ -39,68 +39,68 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x18'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <target chassis='2' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='3' port='0x20'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + <target chassis='3' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </controller> <controller type='pci' index='4' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='4' port='0x28'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + <target chassis='4' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </controller> <controller type='pci' index='5' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='5' port='0x30'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + <target chassis='5' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </controller> <controller type='pci' index='6' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='6' port='0x38'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + <target chassis='6' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </controller> <controller type='pci' index='7' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='7' port='0x40'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> + <target chassis='7' port='0x16'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/> </controller> <controller type='pci' index='8' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='8' port='0x48'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + <target chassis='8' port='0x17'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/> </controller> <controller type='pci' index='9' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='9' port='0x50'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + <target chassis='9' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </controller> <controller type='pci' index='10' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='10' port='0x58'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + <target chassis='10' port='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </controller> <controller type='pci' index='11' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='11' port='0x60'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> + <target chassis='11' port='0x1a'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/> </controller> <controller type='pci' index='12' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='12' port='0x68'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/> + <target chassis='12' port='0x1b'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/> </controller> <controller type='pci' index='13' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='13' port='0x70'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0e' function='0x0'/> + <target chassis='13' port='0x1c'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/> </controller> <controller type='pci' index='14' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='14' port='0x78'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0f' function='0x0'/> + <target chassis='14' port='0x1d'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/> </controller> <filesystem type='mount' accessmode='passthrough'> <source dir='/export/to/guest'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml index 8e727fb..7c74b60 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml @@ -36,63 +36,63 @@ </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'/> + <target chassis='4' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </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'/> + <target chassis='5' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </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'/> + <target chassis='6' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </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'/> + <target chassis='7' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </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'/> + <target chassis='8' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </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'/> + <target chassis='9' port='0x16'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/> </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'/> + <target chassis='10' port='0x17'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/> </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'/> + <target chassis='11' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' 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'/> + <target chassis='12' port='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </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'/> + <target chassis='13' port='0x1a'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/> </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'/> + <target chassis='14' port='0x1b'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/> </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'/> + <target chassis='15' port='0x1c'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/> </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml index 236d955..3bbd99f 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml @@ -50,28 +50,28 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x18'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <target chassis='2' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='3' port='0x20'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + <target chassis='3' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </controller> <controller type='pci' index='4' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='4' port='0x28'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + <target chassis='4' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </controller> <controller type='pci' index='5' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='5' port='0x30'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + <target chassis='5' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </controller> <controller type='pci' index='6' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='6' port='0x38'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + <target chassis='6' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </controller> <interface type='user'> <mac address='52:54:00:9a:e6:c6'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml index c4bd357..d2fa885 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml @@ -36,63 +36,63 @@ </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'/> + <target chassis='4' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </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'/> + <target chassis='5' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </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'/> + <target chassis='6' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </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'/> + <target chassis='7' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </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'/> + <target chassis='8' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </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'/> + <target chassis='9' port='0x16'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/> </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'/> + <target chassis='10' port='0x17'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/> </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'/> + <target chassis='11' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' 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'/> + <target chassis='12' port='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </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'/> + <target chassis='13' port='0x1a'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/> </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'/> + <target chassis='14' port='0x1b'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/> </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'/> + <target chassis='15' port='0x1c'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/> </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0'/> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 569a375..845e935 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -850,11 +850,13 @@ mymain(void) DO_TEST("pcie-root-port", 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_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("pcie-switch-upstream-port", 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_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("pcie-switch-downstream-port",

On Tue, Jan 10, 2017 at 03:51:21PM -0500, Laine Stump wrote:
On 12/19/2016 10:23 AM, Laine Stump wrote:
Set the VIR_PCI_CONNECT_AGGREGATE_SLOT flag for pcie-root-ports so that they will be assigned to all the functions on a slot.
Some qemu test case outputs had to be adjusted due to the pcie-root-ports now being put on multiple functions. ---
ARGH!
In my final rebase before pushing, I pulled in Andrea's patches that switch aarch64/virt to using PCI by default, and the test case for that resulted in a make check failure:
564) QEMU XML-2-ARGV aarch64-virtio-pci-default ... libvirt: QEMU Driver error : unsupported configuration: 'multifunction=on' is not supported with this QEMU binary FAILED
Is it really true that the aarch64 qemu doesn't support multifunction devices? If so, that really needs to be fixed. In the meantime, this means I
aarch64 qemu does support multifunction. It's been a while since I experimented with it, but it worked when I did. Maybe just a make check fix is needed? Thanks, drew
still can't push my patches, because doing so will break aarch64. I'll try to come up with a patch to conditionalize AGGREGATE_SLOT on support for multifunction (which I suppose I should have done to begin with, but I wouldn't have expected that a platform that supports PCIe doesn't support multifunction devices :-/)
src/conf/domain_addr.c | 2 +- .../qemuxml2argv-pcie-root-port.args | 5 +- .../qemuxml2argv-pcie-switch-upstream-port.args | 5 +- .../qemuxml2argv-q35-default-devices-only.args | 7 +-- .../qemuxml2argv-q35-multifunction.args | 12 +++++ .../qemuxml2argv-q35-multifunction.xml | 11 +++++ .../qemuxml2argv-q35-pcie-autoadd.args | 30 ++++++------ tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args | 28 ++++++----- .../qemuxml2argv-q35-virt-manager-basic.args | 13 ++--- .../qemuxml2argv-q35-virtio-pci.args | 28 ++++++----- tests/qemuxml2argvtest.c | 2 + .../qemuxml2xmlout-pcie-root-port.xml | 2 +- .../qemuxml2xmlout-pcie-switch-upstream-port.xml | 4 +- .../qemuxml2xmlout-q35-default-devices-only.xml | 8 ++-- .../qemuxml2xmlout-q35-multifunction.xml | 55 ++++++++++++++++++++++ .../qemuxml2xmlout-q35-pcie-autoadd.xml | 52 ++++++++++---------- .../qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml | 48 +++++++++---------- .../qemuxml2xmlout-q35-virt-manager-basic.xml | 20 ++++---- .../qemuxml2xmlout-q35-virtio-pci.xml | 48 +++++++++---------- tests/qemuxml2xmltest.c | 2 + 20 files changed, 237 insertions(+), 145 deletions(-)
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 18421e0..d60b1d9 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -63,7 +63,7 @@ virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) return VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: - return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT; + return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT | VIR_PCI_CONNECT_AGGREGATE_SLOT; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: return VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args index 27d5164..9a71281 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root-port.args @@ -18,8 +18,9 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x1a,chassis=40,id=pci.4,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x1a,chassis=40,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \ -device ide-drive,bus=ide.0,drive=drive-sata0-0-0,id=sata0-0-0 \ -device qxl-vga,id=video0,ram_size=67108864,vram_size=33554432,bus=pcie.0,\ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args b/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args index 93d16b8..10aedd5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcie-switch-upstream-port.args @@ -18,8 +18,9 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=4,id=pci.4,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ -device x3130-upstream,id=pci.5,bus=pci.3,addr=0x0 \ -device x3130-upstream,id=pci.6,bus=pci.4,addr=0x0 \ -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args index 9d13466..30fc9b7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-default-devices-only.args @@ -16,8 +16,9 @@ QEMU_AUDIO_DRV=none \ -monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \ -no-acpi \ -boot c \ --device ioh3420,port=0x8,chassis=1,id=pci.1,bus=pcie.0,addr=0x1 \ --device ioh3420,port=0x10,chassis=2,id=pci.2,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=3,id=pci.3,bus=pcie.0,addr=0x3 \ +-device ioh3420,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x1 \ +-device ioh3420,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ +-device ioh3420,port=0xa,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \ -device nec-usb-xhci,id=usb,bus=pci.1,addr=0x0 \ -device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args index de1a4a4..1b60744 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.args @@ -27,5 +27,17 @@ addr=0x3.0x1 \ -device ioh3420,port=0x20,chassis=6,id=pci.6,bus=pcie.0,multifunction=off,\ addr=0x4 \ -device ioh3420,port=0x21,chassis=7,id=pci.7,bus=pcie.0,addr=0x4.0x1 \ +-device ioh3420,port=0x8,chassis=8,id=pci.8,bus=pcie.0,multifunction=on,\ +addr=0x1 \ +-device ioh3420,port=0x9,chassis=9,id=pci.9,bus=pcie.0,addr=0x1.0x1 \ +-device ioh3420,port=0xa,chassis=10,id=pci.10,bus=pcie.0,addr=0x1.0x2 \ +-device ioh3420,port=0xb,chassis=11,id=pci.11,bus=pcie.0,addr=0x1.0x3 \ +-device ioh3420,port=0xc,chassis=12,id=pci.12,bus=pcie.0,addr=0x1.0x4 \ +-device ioh3420,port=0xd,chassis=13,id=pci.13,bus=pcie.0,addr=0x1.0x5 \ +-device ioh3420,port=0xe,chassis=14,id=pci.14,bus=pcie.0,addr=0x1.0x6 \ +-device ioh3420,port=0xf,chassis=15,id=pci.15,bus=pcie.0,addr=0x1.0x7 \ +-device ioh3420,port=0x13,chassis=16,id=pci.16,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=17,id=pci.17,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=18,id=pci.18,bus=pcie.0,addr=0x2.0x5 \ -device nec-usb-xhci,id=usb,bus=pci.1,addr=0x0 \ -device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml index b1f3c5e..c1edca1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-multifunction.xml @@ -36,5 +36,16 @@ <controller type='pci' model='pcie-root-port'> <address type='pci' slot='4' function='1'/> </controller> + <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'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args index ba26326..f3d44c0 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie-autoadd.args @@ -16,20 +16,22 @@ QEMU_AUDIO_DRV=none \ -monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \ -no-acpi \ -boot c \ --device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=2,id=pci.2,bus=pcie.0,addr=0x3 \ --device ioh3420,port=0x20,chassis=3,id=pci.3,bus=pcie.0,addr=0x4 \ --device ioh3420,port=0x28,chassis=4,id=pci.4,bus=pcie.0,addr=0x5 \ --device ioh3420,port=0x30,chassis=5,id=pci.5,bus=pcie.0,addr=0x6 \ --device ioh3420,port=0x38,chassis=6,id=pci.6,bus=pcie.0,addr=0x7 \ --device ioh3420,port=0x40,chassis=7,id=pci.7,bus=pcie.0,addr=0x8 \ --device ioh3420,port=0x48,chassis=8,id=pci.8,bus=pcie.0,addr=0x9 \ --device ioh3420,port=0x50,chassis=9,id=pci.9,bus=pcie.0,addr=0xa \ --device ioh3420,port=0x58,chassis=10,id=pci.10,bus=pcie.0,addr=0xb \ --device ioh3420,port=0x60,chassis=11,id=pci.11,bus=pcie.0,addr=0xc \ --device ioh3420,port=0x68,chassis=12,id=pci.12,bus=pcie.0,addr=0xd \ --device ioh3420,port=0x70,chassis=13,id=pci.13,bus=pcie.0,addr=0xe \ --device ioh3420,port=0x78,chassis=14,id=pci.14,bus=pcie.0,addr=0xf \ +-device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x5 \ +-device ioh3420,port=0x16,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x6 \ +-device ioh3420,port=0x17,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x7 \ +-device ioh3420,port=0x18,chassis=9,id=pci.9,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=10,id=pci.10,bus=pcie.0,addr=0x3.0x1 \ +-device ioh3420,port=0x1a,chassis=11,id=pci.11,bus=pcie.0,addr=0x3.0x2 \ +-device ioh3420,port=0x1b,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x3 \ +-device ioh3420,port=0x1c,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x4 \ +-device ioh3420,port=0x1d,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x5 \ -device nec-usb-xhci,id=usb,bus=pci.6,addr=0x0 \ -device virtio-scsi-pci,id=scsi0,bus=pci.5,addr=0x0 \ -device virtio-serial-pci,id=virtio-serial0,bus=pci.4,addr=0x0 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args index 2738749..3b507f3 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-pcie.args @@ -18,19 +18,21 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device 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 ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ --device ioh3420,port=0x70,chassis=15,id=pci.15,bus=pcie.0,addr=0xe \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x5 \ +-device ioh3420,port=0x16,chassis=9,id=pci.9,bus=pcie.0,addr=0x2.0x6 \ +-device ioh3420,port=0x17,chassis=10,id=pci.10,bus=pcie.0,addr=0x2.0x7 \ +-device ioh3420,port=0x18,chassis=11,id=pci.11,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x1 \ +-device ioh3420,port=0x1a,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x2 \ +-device ioh3420,port=0x1b,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x3 \ +-device ioh3420,port=0x1c,chassis=15,id=pci.15,bus=pcie.0,addr=0x3.0x4 \ -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 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args index 60af251..e139e52 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args @@ -18,12 +18,13 @@ QEMU_AUDIO_DRV=spice \ -global ICH9-LPC.disable_s3=1 \ -global ICH9-LPC.disable_s4=1 \ -boot c \ --device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,addr=0x2 \ --device ioh3420,port=0x18,chassis=2,id=pci.2,bus=pcie.0,addr=0x3 \ --device ioh3420,port=0x20,chassis=3,id=pci.3,bus=pcie.0,addr=0x4 \ --device ioh3420,port=0x28,chassis=4,id=pci.4,bus=pcie.0,addr=0x5 \ --device ioh3420,port=0x30,chassis=5,id=pci.5,bus=pcie.0,addr=0x6 \ --device ioh3420,port=0x38,chassis=6,id=pci.6,bus=pcie.0,addr=0x7 \ +-device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x5 \ -device nec-usb-xhci,id=usb,bus=pci.2,addr=0x0 \ -device virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 \ -drive file=/var/lib/libvirt/images/basic.qcow2,format=qcow2,if=none,\ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args index cada05e..a1025dc 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virtio-pci.args @@ -18,19 +18,21 @@ QEMU_AUDIO_DRV=none \ -boot c \ -device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ -device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \ --device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \ --device 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 ioh3420,port=0x68,chassis=14,id=pci.14,bus=pcie.0,addr=0xd \ --device ioh3420,port=0x70,chassis=15,id=pci.15,bus=pcie.0,addr=0xe \ +-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,\ +addr=0x2 \ +-device ioh3420,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1 \ +-device ioh3420,port=0x12,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x2 \ +-device ioh3420,port=0x13,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x3 \ +-device ioh3420,port=0x14,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x4 \ +-device ioh3420,port=0x15,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x5 \ +-device ioh3420,port=0x16,chassis=9,id=pci.9,bus=pcie.0,addr=0x2.0x6 \ +-device ioh3420,port=0x17,chassis=10,id=pci.10,bus=pcie.0,addr=0x2.0x7 \ +-device ioh3420,port=0x18,chassis=11,id=pci.11,bus=pcie.0,multifunction=on,\ +addr=0x3 \ +-device ioh3420,port=0x19,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x1 \ +-device ioh3420,port=0x1a,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x2 \ +-device ioh3420,port=0x1b,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x3 \ +-device ioh3420,port=0x1c,chassis=15,id=pci.15,bus=pcie.0,addr=0x3.0x4 \ -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 \ diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c6f9593..becb492 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1978,6 +1978,7 @@ mymain(void) QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_ICH9_AHCI, + QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("autoindex", @@ -2021,6 +2022,7 @@ mymain(void) QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_DEVICE_X3130_UPSTREAM, QEMU_CAPS_ICH9_AHCI, + QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("pcie-switch-downstream-port", diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml index a4ff820..082dd6c 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-root-port.xml @@ -37,7 +37,7 @@ <controller type='pci' index='4' model='pcie-root-port'> <model name='ioh3420'/> <target chassis='40' port='0x1a'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='sata' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml index 53e10d0..52c9177 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcie-switch-upstream-port.xml @@ -36,8 +36,8 @@ </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'/> + <target chassis='4' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='pci' index='5' model='pcie-switch-upstream-port'> <model name='x3130-upstream'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml index e64b80c..e8a7d8c 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-default-devices-only.xml @@ -28,13 +28,13 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x10'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + <target chassis='2' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> </controller> <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='3' port='0x18'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <target chassis='3' port='0xa'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml index 3d5cd76..06b8144 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-multifunction.xml @@ -50,6 +50,61 @@ <target chassis='7' port='0x21'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/> </controller> + <controller type='pci' index='8' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='8' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='pci' index='9' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='9' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='10' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='10' port='0xa'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='11' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='11' port='0xb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/> + </controller> + <controller type='pci' index='12' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='12' port='0xc'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/> + </controller> + <controller type='pci' index='13' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='13' port='0xd'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x5'/> + </controller> + <controller type='pci' index='14' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='14' port='0xe'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x6'/> + </controller> + <controller type='pci' index='15' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='15' port='0xf'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x7'/> + </controller> + <controller type='pci' index='16' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='16' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> + </controller> + <controller type='pci' index='17' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='17' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> + </controller> + <controller type='pci' index='18' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='18' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> + </controller> <controller type='usb' index='0' model='nec-xhci'> <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </controller> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml index 3742e14..28862c9 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie-autoadd.xml @@ -39,68 +39,68 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x18'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <target chassis='2' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='3' port='0x20'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + <target chassis='3' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </controller> <controller type='pci' index='4' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='4' port='0x28'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + <target chassis='4' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </controller> <controller type='pci' index='5' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='5' port='0x30'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + <target chassis='5' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </controller> <controller type='pci' index='6' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='6' port='0x38'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + <target chassis='6' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </controller> <controller type='pci' index='7' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='7' port='0x40'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> + <target chassis='7' port='0x16'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/> </controller> <controller type='pci' index='8' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='8' port='0x48'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + <target chassis='8' port='0x17'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/> </controller> <controller type='pci' index='9' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='9' port='0x50'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + <target chassis='9' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </controller> <controller type='pci' index='10' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='10' port='0x58'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + <target chassis='10' port='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </controller> <controller type='pci' index='11' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='11' port='0x60'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> + <target chassis='11' port='0x1a'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/> </controller> <controller type='pci' index='12' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='12' port='0x68'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/> + <target chassis='12' port='0x1b'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/> </controller> <controller type='pci' index='13' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='13' port='0x70'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0e' function='0x0'/> + <target chassis='13' port='0x1c'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/> </controller> <controller type='pci' index='14' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='14' port='0x78'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x0f' function='0x0'/> + <target chassis='14' port='0x1d'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/> </controller> <filesystem type='mount' accessmode='passthrough'> <source dir='/export/to/guest'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml index 8e727fb..7c74b60 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-pcie.xml @@ -36,63 +36,63 @@ </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'/> + <target chassis='4' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </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'/> + <target chassis='5' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </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'/> + <target chassis='6' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </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'/> + <target chassis='7' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </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'/> + <target chassis='8' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </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'/> + <target chassis='9' port='0x16'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/> </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'/> + <target chassis='10' port='0x17'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/> </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'/> + <target chassis='11' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' 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'/> + <target chassis='12' port='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </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'/> + <target chassis='13' port='0x1a'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/> </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'/> + <target chassis='14' port='0x1b'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/> </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'/> + <target chassis='15' port='0x1c'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/> </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml index 236d955..3bbd99f 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml @@ -50,28 +50,28 @@ </controller> <controller type='pci' index='2' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='2' port='0x18'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + <target chassis='2' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </controller> <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='3' port='0x20'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + <target chassis='3' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </controller> <controller type='pci' index='4' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='4' port='0x28'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + <target chassis='4' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </controller> <controller type='pci' index='5' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='5' port='0x30'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + <target chassis='5' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </controller> <controller type='pci' index='6' model='pcie-root-port'> <model name='ioh3420'/> - <target chassis='6' port='0x38'/> - <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + <target chassis='6' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </controller> <interface type='user'> <mac address='52:54:00:9a:e6:c6'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml index c4bd357..d2fa885 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virtio-pci.xml @@ -36,63 +36,63 @@ </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'/> + <target chassis='4' port='0x11'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/> </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'/> + <target chassis='5' port='0x12'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/> </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'/> + <target chassis='6' port='0x13'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/> </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'/> + <target chassis='7' port='0x14'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/> </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'/> + <target chassis='8' port='0x15'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/> </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'/> + <target chassis='9' port='0x16'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/> </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'/> + <target chassis='10' port='0x17'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/> </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'/> + <target chassis='11' port='0x18'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' 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'/> + <target chassis='12' port='0x19'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </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'/> + <target chassis='13' port='0x1a'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/> </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'/> + <target chassis='14' port='0x1b'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/> </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'/> + <target chassis='15' port='0x1c'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/> </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0'/> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 569a375..845e935 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -850,11 +850,13 @@ mymain(void) DO_TEST("pcie-root-port", 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_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("pcie-switch-upstream-port", 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_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_QXL); DO_TEST("pcie-switch-downstream-port",

On 01/11/2017 03:56 AM, Andrew Jones wrote:
On Tue, Jan 10, 2017 at 03:51:21PM -0500, Laine Stump wrote:
On 12/19/2016 10:23 AM, Laine Stump wrote:
Set the VIR_PCI_CONNECT_AGGREGATE_SLOT flag for pcie-root-ports so that they will be assigned to all the functions on a slot.
Some qemu test case outputs had to be adjusted due to the pcie-root-ports now being put on multiple functions. --- ARGH!
In my final rebase before pushing, I pulled in Andrea's patches that switch aarch64/virt to using PCI by default, and the test case for that resulted in a make check failure:
564) QEMU XML-2-ARGV aarch64-virtio-pci-default ... libvirt: QEMU Driver error : unsupported configuration: 'multifunction=on' is not supported with this QEMU binary FAILED
Is it really true that the aarch64 qemu doesn't support multifunction devices? If so, that really needs to be fixed. In the meantime, this means I aarch64 qemu does support multifunction. It's been a while since I experimented with it, but it worked when I did. Maybe just a make check fix is needed?
Derp. Of course - it's just a missing capability flag in Andrea's new test case (which wasn't needed until I started doing stuff that required multifunction)m *not* a missing capability in the aarch64 qemu binary. Once I fix that it's of course passing the test. Thanks for jarring my brain into proper thought!

On Tue, 2017-01-10 at 15:51 -0500, Laine Stump wrote:
ARGH!
ARGH to you too :)
In my final rebase before pushing, I pulled in Andrea's patches that switch aarch64/virt to using PCI by default, and the test case for that resulted in a make check failure: 564) QEMU XML-2-ARGV aarch64-virtio-pci-default ... libvirt: QEMU Driver error : unsupported configuration: 'multifunction=on' is not supported with this QEMU binary FAILED Is it really true that the aarch64 qemu doesn't support multifunction devices? If so, that really needs to be fixed. In the meantime, this means I still can't push my patches, because doing so will break aarch64.
I think the only problem is that current aarch64 test cases don't enable the QEMU_CAPS_PCI_MULTIFUNCTION capability. I will try this on actual hardware now and get back to you, but really that's all you should have to do in order not to break the test suite with your changes.
I'll try to come up with a patch to conditionalize AGGREGATE_SLOT on support for multifunction (which I suppose I should have done to begin with, but I wouldn't have expected that a platform that supports PCIe doesn't support multifunction devices :-/)
That's a good idea in any case, yes. However, realistically speaking, I think your initial intuition that all platforms that support PCIe also support multifunction still holds as far as real-world scenarios are concerned. -- Andrea Bolognani / Red Hat / Virtualization

On 01/11/2017 04:13 AM, Andrea Bolognani wrote:
On Tue, 2017-01-10 at 15:51 -0500, Laine Stump wrote:
ARGH! ARGH to you too :)
(Talk like a Pirate Day isn't until Sept 19.)
In my final rebase before pushing, I pulled in Andrea's patches that switch aarch64/virt to using PCI by default, and the test case for that resulted in a make check failure:
564) QEMU XML-2-ARGV aarch64-virtio-pci-default ... libvirt: QEMU Driver error : unsupported configuration: 'multifunction=on' is not supported with this QEMU binary FAILED
Is it really true that the aarch64 qemu doesn't support multifunction devices? If so, that really needs to be fixed. In the meantime, this means I still can't push my patches, because doing so will break aarch64. I think the only problem is that current aarch64 test cases don't enable the QEMU_CAPS_PCI_MULTIFUNCTION capability.
Yes. That's correct. I don't know what I was (or wasn't) thinking. It's all fixed now, and ready to push.
I will try this on actual hardware now and get back to you, but really that's all you should have to do in order not to break the test suite with your changes.
I'll try to come up with a patch to conditionalize AGGREGATE_SLOT on support for multifunction (which I suppose I should have done to begin with, but I wouldn't have expected that a platform that supports PCIe doesn't support multifunction devices :-/) That's a good idea in any case, yes.
Yeah, I'm planning on doing that in a cleanup patch. I wrote one last night but it was somehow broken and I was too tired to figure out why, so I'll save it for later.
However, realistically speaking, I think your initial intuition that all platforms that support PCIe also support multifunction still holds as far as real-world scenarios are concerned.
-- Andrea Bolognani / Red Hat / Virtualization
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
participants (4)
-
Andrea Bolognani
-
Andrew Jones
-
Daniel P. Berrange
-
Laine Stump