]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Tweak auto adding PCI bridge controller when extending default PCI bus
authorErik Skultety <eskultet@redhat.com>
Thu, 15 Jan 2015 13:14:17 +0000 (14:14 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 16 Jan 2015 09:38:29 +0000 (10:38 +0100)
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

index a2fcb649b3e35d4d20d9d3c4e5c4cf66cd240c2a..8091fb3d456d9b336c7beaf7553034475e0ed548 100644 (file)
@@ -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];