In case we find out, there are more PCI devices to be connected
than there are available slots on the default PCI bus, we automatically add a
new bus and a related PCI bridge controller as well. As there are no free slots
left on the default PCI bus, PCI bridge controller gets a free slot on a
newly created PCI bus which causes qemu to refuse to start the guest.
This fix introduces a new function qemuDomainPCIBusFullyReserved which
is checked right before we possibly try to reserve a slot for PCI bridge
controller.
Resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1132900
---
src/qemu/qemu_command.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3346e95..06def5f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1445,6 +1445,18 @@ qemuDomainSupportsPCI(virDomainDefPtr def)
return false;
}
+static bool
+qemuDomainPCIBusFullyReserved(virDomainPCIAddressBusPtr bus)
+{
+ size_t i;
+
+ for (i = bus->minSlot; i <= bus->maxSlot; i++)
+ if (!bus->slots[i])
+ return false;
+
+ return true;
+}
+
int
qemuDomainAssignPCIAddresses(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
@@ -1479,9 +1491,15 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
goto cleanup;
if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
goto cleanup;
- /* Reserve 1 extra slot for a (potential) bridge */
- if (virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 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];
--
1.9.3