[libvirt] [PATCH v2 0/4] qemu: fix PCI bridge auto-add to extend default bus

Erik Skultety (4): qemu: reorder PCI slot assignment functions qemu: move PCI slot assignment for PIIX3, Q35 into a separate function qemu: Fix auto-adding PCI bridge when all slots are reserved qemu: Add check for PCI bridge placement if there are too many PCI devices src/qemu/qemu_command.c | 265 ++++++++++++++++++++++++++++-------------------- 1 file changed, 154 insertions(+), 111 deletions(-) -- 1.9.3

In previous commit a chunk of code got moved in to a separate static function qemuValidateDevicePCISlotsChipsets. This function then invokes chipset specific functions which are defined as static as well. For these reasons it is necessary to either have a forward declaration or slightly reorder definitions. --- src/qemu/qemu_command.c | 194 ++++++++++++++++++++++++------------------------ 1 file changed, 98 insertions(+), 96 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 9a2dcec..336a3d3 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1458,102 +1458,6 @@ qemuDomainPCIBusFullyReserved(virDomainPCIAddressBusPtr bus) return true; } -int -qemuDomainAssignPCIAddresses(virDomainDefPtr def, - virQEMUCapsPtr qemuCaps, - virDomainObjPtr obj) -{ - int ret = -1; - virDomainPCIAddressSetPtr addrs = NULL; - qemuDomainObjPrivatePtr priv = NULL; - - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { - int max_idx = -1; - int nbuses = 0; - size_t i; - int rv; - virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI; - - for (i = 0; i < def->ncontrollers; i++) { - if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) { - if ((int) def->controllers[i]->idx > max_idx) - max_idx = def->controllers[i]->idx; - } - } - - nbuses = max_idx + 1; - - if (nbuses > 0 && - virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) { - virDomainDeviceInfo info; - - /* 1st pass to figure out how many PCI bridges we need */ - if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, true))) - goto cleanup; - if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) - goto cleanup; - - for (i = 0; i < addrs->nbuses; i++) { - if (!qemuDomainPCIBusFullyReserved(&addrs->buses[i])) { - - /* Reserve 1 extra slot for a (potential) bridge */ - if (virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0) - goto cleanup; - } - } - - for (i = 1; i < addrs->nbuses; i++) { - virDomainPCIAddressBusPtr bus = &addrs->buses[i]; - - if ((rv = virDomainDefMaybeAddController( - def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, - i, bus->model)) < 0) - goto cleanup; - /* If we added a new bridge, we will need one more address */ - if (rv > 0 && - virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0) - goto cleanup; - } - nbuses = addrs->nbuses; - virDomainPCIAddressSetFree(addrs); - addrs = NULL; - - } else if (max_idx > 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("PCI bridges are not supported " - "by this QEMU binary")); - goto cleanup; - } - - if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, false))) - goto cleanup; - - if (qemuDomainSupportsPCI(def)) { - if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) - goto cleanup; - } - } - - if (obj && obj->privateData) { - priv = obj->privateData; - if (addrs) { - /* if this is the live domain object, we persist the PCI addresses*/ - virDomainPCIAddressSetFree(priv->pciaddrs); - priv->persistentAddrs = 1; - priv->pciaddrs = addrs; - addrs = NULL; - } else { - priv->persistentAddrs = 0; - } - } - - ret = 0; - - cleanup: - virDomainPCIAddressSetFree(addrs); - - return ret; -} int qemuDomainAssignAddresses(virDomainDefPtr def, virQEMUCapsPtr qemuCaps, @@ -1971,6 +1875,104 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, } +int +qemuDomainAssignPCIAddresses(virDomainDefPtr def, + virQEMUCapsPtr qemuCaps, + virDomainObjPtr obj) +{ + int ret = -1; + virDomainPCIAddressSetPtr addrs = NULL; + qemuDomainObjPrivatePtr priv = NULL; + + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + int max_idx = -1; + int nbuses = 0; + size_t i; + int rv; + virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI; + + for (i = 0; i < def->ncontrollers; i++) { + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) { + if ((int) def->controllers[i]->idx > max_idx) + max_idx = def->controllers[i]->idx; + } + } + + nbuses = max_idx + 1; + + if (nbuses > 0 && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) { + virDomainDeviceInfo info; + + /* 1st pass to figure out how many PCI bridges we need */ + if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, true))) + goto cleanup; + if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) + goto cleanup; + + for (i = 0; i < addrs->nbuses; i++) { + if (!qemuDomainPCIBusFullyReserved(&addrs->buses[i])) { + + /* Reserve 1 extra slot for a (potential) bridge */ + if (virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0) + goto cleanup; + } + } + + for (i = 1; i < addrs->nbuses; i++) { + virDomainPCIAddressBusPtr bus = &addrs->buses[i]; + + if ((rv = virDomainDefMaybeAddController( + def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, + i, bus->model)) < 0) + goto cleanup; + /* If we added a new bridge, we will need one more address */ + if (rv > 0 && + virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0) + goto cleanup; + } + nbuses = addrs->nbuses; + virDomainPCIAddressSetFree(addrs); + addrs = NULL; + + } else if (max_idx > 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("PCI bridges are not supported " + "by this QEMU binary")); + goto cleanup; + } + + if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, false))) + goto cleanup; + + if (qemuDomainSupportsPCI(def)) { + if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) + goto cleanup; + } + } + + if (obj && obj->privateData) { + priv = obj->privateData; + if (addrs) { + /* if this is the live domain object, we persist the PCI addresses*/ + virDomainPCIAddressSetFree(priv->pciaddrs); + priv->persistentAddrs = 1; + priv->pciaddrs = addrs; + addrs = NULL; + } else { + priv->persistentAddrs = 0; + } + } + + ret = 0; + + cleanup: + virDomainPCIAddressSetFree(addrs); + + return ret; +} + + /* * This assigns static PCI slots to all configured devices. * The ordering here is chosen to match the ordering used -- 1.9.3

On 01/23/2015 01:17 PM, Erik Skultety wrote:
In previous commit a chunk of code got moved in to a separate static function qemuValidateDevicePCISlotsChipsets. This function then invokes chipset specific functions which are defined as static as well. For these reasons it is necessary to either have a forward declaration or slightly reorder definitions. --- src/qemu/qemu_command.c | 194 ++++++++++++++++++++++++------------------------ 1 file changed, 98 insertions(+), 96 deletions(-)
ACK to the patch, this is just code movement. But the commit message is not accurate anymore. I've reworded it and pushed the patch. Jan

On 01/23/2015 01:17 PM, Erik Skultety wrote:
In previous commit a chunk of code got moved in to a separate static function qemuValidateDevicePCISlotsChipsets. This function then invokes chipset specific functions which are defined as static as well. For these reasons it is necessary to either have a forward declaration or slightly reorder definitions. --- src/qemu/qemu_command.c | 194 ++++++++++++++++++++++++------------------------ 1 file changed, 98 insertions(+), 96 deletions(-)
ACK to the patch, this is just code movement. But the commit message is not accurate anymore. I've reworded it and pushed the patch. Jan

In order to be able to test for fully reserved PCI buses, assignment of PCI slots for integrated devices needs to be moved to a separate function. This also might be a good preparation if we decide to add support for other chipsets as well. --- src/qemu/qemu_command.c | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 336a3d3..457c777 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1874,6 +1874,27 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, return ret; } +static int +qemuValidateDevicePCISlotsChipsets(virDomainDefPtr def, + virQEMUCapsPtr qemuCaps, + virDomainPCIAddressSetPtr addrs) +{ + if ((STRPREFIX(def->os.machine, "pc-0.") || + STRPREFIX(def->os.machine, "pc-1.") || + STRPREFIX(def->os.machine, "pc-i440") || + STREQ(def->os.machine, "pc") || + STRPREFIX(def->os.machine, "rhel")) && + qemuValidateDevicePCISlotsPIIX3(def, qemuCaps, addrs) < 0) { + return -1; + } + + if (qemuDomainMachineIsQ35(def) && + qemuDomainValidateDevicePCISlotsQ35(def, qemuCaps, addrs) < 0) { + return -1; + } + + return 0; +} int qemuDomainAssignPCIAddresses(virDomainDefPtr def, @@ -1907,6 +1928,10 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, /* 1st pass to figure out how many PCI bridges we need */ if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, true))) goto cleanup; + + if (qemuValidateDevicePCISlotsChipsets(def, qemuCaps, addrs) < 0) + goto cleanup; + if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) goto cleanup; @@ -1946,6 +1971,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, goto cleanup; if (qemuDomainSupportsPCI(def)) { + if (qemuValidateDevicePCISlotsChipsets(def, qemuCaps, addrs) < 0) + goto cleanup; + if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) goto cleanup; } @@ -1990,6 +2018,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, * - PIIX3 ISA bridge, IDE controller, something else unknown, USB controller (slot 1) * - Video (slot 2) * + * - These integrated devices were already added by + * qemuValidateDevicePCISlotsChipsets invoked right before this function + * * Incrementally assign slots from 3 onwards: * * - Net @@ -2007,27 +2038,13 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, */ int qemuAssignDevicePCISlots(virDomainDefPtr def, - virQEMUCapsPtr qemuCaps, + virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED, virDomainPCIAddressSetPtr addrs) { size_t i, j; virDomainPCIConnectFlags flags; virDevicePCIAddress tmp_addr; - if ((STRPREFIX(def->os.machine, "pc-0.") || - STRPREFIX(def->os.machine, "pc-1.") || - STRPREFIX(def->os.machine, "pc-i440") || - STREQ(def->os.machine, "pc") || - STRPREFIX(def->os.machine, "rhel")) && - qemuValidateDevicePCISlotsPIIX3(def, qemuCaps, addrs) < 0) { - goto error; - } - - if (qemuDomainMachineIsQ35(def) && - qemuDomainValidateDevicePCISlotsQ35(def, qemuCaps, addrs) < 0) { - goto error; - } - /* PCI controllers */ for (i = 0; i < def->ncontrollers; i++) { if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) { -- 1.9.3

On 01/23/2015 01:17 PM, Erik Skultety wrote:
In order to be able to test for fully reserved PCI buses, assignment of PCI slots for integrated devices needs to be moved to a separate function. This also might be a good preparation if we decide to add support for other chipsets as well. --- src/qemu/qemu_command.c | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 336a3d3..457c777 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1874,6 +1874,27 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, return ret; }
+static int +qemuValidateDevicePCISlotsChipsets(virDomainDefPtr def, + virQEMUCapsPtr qemuCaps, + virDomainPCIAddressSetPtr addrs) +{ + if ((STRPREFIX(def->os.machine, "pc-0.") || + STRPREFIX(def->os.machine, "pc-1.") || + STRPREFIX(def->os.machine, "pc-i440") || + STREQ(def->os.machine, "pc") || + STRPREFIX(def->os.machine, "rhel")) && + qemuValidateDevicePCISlotsPIIX3(def, qemuCaps, addrs) < 0) { + return -1; + } + + if (qemuDomainMachineIsQ35(def) && + qemuDomainValidateDevicePCISlotsQ35(def, qemuCaps, addrs) < 0) { + return -1; + } + + return 0; +}
int qemuDomainAssignPCIAddresses(virDomainDefPtr def, @@ -1907,6 +1928,10 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, /* 1st pass to figure out how many PCI bridges we need */ if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, true))) goto cleanup; + + if (qemuValidateDevicePCISlotsChipsets(def, qemuCaps, addrs) < 0) + goto cleanup; + if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) goto cleanup;
@@ -1946,6 +1971,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, goto cleanup;
if (qemuDomainSupportsPCI(def)) { + if (qemuValidateDevicePCISlotsChipsets(def, qemuCaps, addrs) < 0) + goto cleanup; + if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) goto cleanup; } @@ -1990,6 +2018,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, * - PIIX3 ISA bridge, IDE controller, something else unknown, USB controller (slot 1) * - Video (slot 2) * + * - These integrated devices were already added by + * qemuValidateDevicePCISlotsChipsets invoked right before this function + * * Incrementally assign slots from 3 onwards: * * - Net @@ -2007,27 +2038,13 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, */ int qemuAssignDevicePCISlots(virDomainDefPtr def, - virQEMUCapsPtr qemuCaps, + virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
We can just remove the parameter if it's not used. ACK and pushed with that change. Jan

Commit 93c8ca tried to fix the issue with auto-adding of a PCI bridge controller, but didn't work properly in all scenarios. This patch provides a better fix of the issue when all slots on a PCI bus are reserved by devices with user specified addresses and no additional bridges need to be created. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1132900 --- src/qemu/qemu_command.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 457c777..a3dedbf 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1910,6 +1910,8 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, int nbuses = 0; size_t i; int rv; + bool buses_reserved = true; + virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI; for (i = 0; i < def->ncontrollers; i++) { @@ -1932,18 +1934,21 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, if (qemuValidateDevicePCISlotsChipsets(def, qemuCaps, addrs) < 0) goto cleanup; - if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) - goto cleanup; - for (i = 0; i < addrs->nbuses; i++) { - if (!qemuDomainPCIBusFullyReserved(&addrs->buses[i])) { - - /* Reserve 1 extra slot for a (potential) bridge */ - if (virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0) - goto cleanup; - } + if (!qemuDomainPCIBusFullyReserved(&addrs->buses[i])) + buses_reserved = false; } + /* Reserve 1 extra slot for a (potential) bridge only if buses + * are not fully reserved yet + */ + if (!buses_reserved && + virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0) + goto cleanup; + + if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) + goto cleanup; + for (i = 1; i < addrs->nbuses; i++) { virDomainPCIAddressBusPtr bus = &addrs->buses[i]; -- 1.9.3

On 01/23/2015 01:17 PM, Erik Skultety wrote:
Commit 93c8ca tried to fix the issue with auto-adding of a PCI bridge controller, but didn't work properly in all scenarios.
This patch provides a better fix of the issue when all slots on a PCI bus are reserved by devices with user specified addresses and no additional bridges need to be created.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1132900 --- src/qemu/qemu_command.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 457c777..a3dedbf 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1910,6 +1910,8 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, int nbuses = 0; size_t i; int rv; + bool buses_reserved = true; + virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI;
for (i = 0; i < def->ncontrollers; i++) { @@ -1932,18 +1934,21 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, if (qemuValidateDevicePCISlotsChipsets(def, qemuCaps, addrs) < 0) goto cleanup;
- if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) - goto cleanup; - for (i = 0; i < addrs->nbuses; i++) { - if (!qemuDomainPCIBusFullyReserved(&addrs->buses[i])) { - - /* Reserve 1 extra slot for a (potential) bridge */ - if (virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0) - goto cleanup; - } + if (!qemuDomainPCIBusFullyReserved(&addrs->buses[i])) + buses_reserved = false; }
+ /* Reserve 1 extra slot for a (potential) bridge only if buses
Indentation is off here.
+ * are not fully reserved yet + */ + if (!buses_reserved && + virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0) + goto cleanup; + + if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) + goto cleanup; + for (i = 1; i < addrs->nbuses; i++) { virDomainPCIAddressBusPtr bus = &addrs->buses[i];
ACK and pushed. Jan

Previous patch of this series fixed the issue with adding a new PCI bridge when all the slots were reserved by devices with user specified addresses. In case there are still some PCI devices waiting to get a slot reserved by qemuAssignDevicePCISlots, this means a new bus needs to be created along with a corresponding bridge controller. By adding an additional check, this scenario now results in a reasonable error instead of generating wrong qemu command line. --- src/qemu/qemu_command.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a3dedbf..870771f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1982,6 +1982,25 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) goto cleanup; } + + for (i = 0; i < def->ncontrollers; i++) { + /* check if every PCI bridge controller's ID is greater than + * the bus it is placed onto + */ + virDomainControllerDefPtr cont = def->controllers[i]; + int idx = cont->idx; + int bus = cont->info.addr.pci.bus; + if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI && + cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE && + idx <= bus) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("failed to create PCI bridge " + "on bus %d: too many devices with fixed " + "addresses"), + bus); + goto cleanup; + } + } } if (obj && obj->privateData) { -- 1.9.3

On 01/23/2015 01:17 PM, Erik Skultety wrote:
Previous patch of this series fixed the issue with adding a new PCI bridge when all the slots were reserved by devices with user specified addresses. In case there are still some PCI devices waiting to get a slot reserved by qemuAssignDevicePCISlots, this means a new bus needs to be created along with a corresponding bridge controller. By adding an additional check, this scenario now results in a reasonable error instead of generating wrong qemu command line. --- src/qemu/qemu_command.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
ACK
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a3dedbf..870771f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1982,6 +1982,25 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) goto cleanup; } + + for (i = 0; i < def->ncontrollers; i++) { + /* check if every PCI bridge controller's ID is greater than + * the bus it is placed onto + */ + virDomainControllerDefPtr cont = def->controllers[i]; + int idx = cont->idx; + int bus = cont->info.addr.pci.bus; + if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI && + cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE && + idx <= bus) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("failed to create PCI bridge " + "on bus %d: too many devices with fixed " + "addresses"), + bus); + goto cleanup; + } + } }
if (obj && obj->privateData) {
I have moved the check into if (qemuDomainSupportsPCI) and pushed the patch. Jan

On 01/23/2015 02:38 PM, Ján Tomko wrote:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a3dedbf..870771f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1982,6 +1982,25 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) goto cleanup; } + + for (i = 0; i < def->ncontrollers; i++) { + /* check if every PCI bridge controller's ID is greater than + * the bus it is placed onto + */ + virDomainControllerDefPtr cont = def->controllers[i]; + int idx = cont->idx; + int bus = cont->info.addr.pci.bus; + if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI && + cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE && + idx <= bus) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("failed to create PCI bridge " + "on bus %d: too many devices with fixed " + "addresses"), + bus); + goto cleanup; + } + } }
if (obj && obj->privateData) {
I have moved the check into if (qemuDomainSupportsPCI) and pushed the patch.
Jan
Thank you. Erik
participants (2)
-
Erik Skultety
-
Ján Tomko