[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
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
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
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:
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 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
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:
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 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
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