[libvirt] [PATCH 2/4] Rearrange VGA/IDE controller address reservation

Daniel P. Berrange berrange at redhat.com
Tue Jul 20 13:09:30 UTC 2010


From: Daniel P. Berrange <dan at berrange.com>

The first VGA and IDE devices need to have fixed PCI address
reservations. Currently this is handled inline with the other
non-primary VGA/IDE devices. The fixed virtio balloon device
at slot 3, ensures auto-assignment skips the slots 1/2. The
virtio address will shortly become configurable though. This
means the reservation of fixed slots needs to be done upfront
to ensure that they don't get re-used for other devices.

This is more or less reverting the previous changeset:

  commit 83acdeaf173b2a1206b755c1ab317cac36facd90
  Author: Daniel P. Berrange <berrange at redhat.com>
  Date:   Wed Feb 3 16:11:29 2010 +0000

  Fix restore of QEMU guests with PCI device reservation

The difference is that this time, instead of unconditionally
reserving the address, we only reserve the address if it was
initially type=none. Addresses of type=pci were handled
earlier in process by qemuDomainPCIAddressSetCreate(). This
ensures restore step doesn't have problems

* src/qemu/qemu_conf.c: Reserve first VGA + IDE address
  upfront
---
 src/qemu/qemu_conf.c |  118 ++++++++++++++++++++++++++------------------------
 1 files changed, 62 insertions(+), 56 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 8e5414a..d89e065 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -2246,12 +2246,56 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
         goto error;
 
     /* PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller)
-     * at slot 1....reserve it later
+     * hardcoded slot=1, multifunction device
      */
+    for (i = 0; i < def->ncontrollers ; i++) {
+        /* First IDE controller lives on the PIIX3 at slot=1, function=1 */
+        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE &&
+            def->controllers[i]->idx == 0) {
+            if (def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+                if (def->controllers[i]->info.addr.pci.domain != 0 ||
+                    def->controllers[i]->info.addr.pci.bus != 0 ||
+                    def->controllers[i]->info.addr.pci.slot != 1 ||
+                    def->controllers[i]->info.addr.pci.function != 1) {
+                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                    _("Primary IDE controller must have PCI address 0:0:1.1"));
+                    goto error;
+                }
+            } else {
+                def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+                def->controllers[i]->info.addr.pci.domain = 0;
+                def->controllers[i]->info.addr.pci.bus = 0;
+                def->controllers[i]->info.addr.pci.slot = 1;
+                def->controllers[i]->info.addr.pci.function = 1;
+                if (qemuDomainPCIAddressReserveSlot(addrs, 1) < 0)
+                    goto error;
+            }
+        }
+    }
 
-    /* VGA at slot 2.... reserve it later */
+    /* First VGA is hardcoded slot=2 */
+    if (def->nvideos > 0) {
+        if (def->videos[0]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+            if (def->videos[0]->info.addr.pci.domain != 0 ||
+                def->videos[0]->info.addr.pci.bus != 0 ||
+                def->videos[0]->info.addr.pci.slot != 2 ||
+                def->videos[0]->info.addr.pci.function != 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("Primary video card must have PCI address 0:0:2.0"));
+                goto error;
+            }
+        } else {
+            def->videos[0]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+            def->videos[0]->info.addr.pci.domain = 0;
+            def->videos[0]->info.addr.pci.bus = 0;
+            def->videos[0]->info.addr.pci.slot = 2;
+            def->videos[0]->info.addr.pci.function = 0;
+            if (qemuDomainPCIAddressReserveSlot(addrs, 2) < 0)
+                goto error;
+        }
+    }
 
-    /* VirtIO Balloon */
+    /* VirtIO balloon always at slot 3 by default */
     if (qemuDomainPCIAddressReserveSlot(addrs, 3) < 0)
         goto error;
 
@@ -2296,66 +2340,28 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
         if (qemuDomainPCIAddressSetNextAddr(addrs, &def->hostdevs[i]->info) < 0)
             goto error;
     }
-    for (i = 0; i < def->nvideos ; i++) {
-        /* First VGA is hardcoded slot=2 */
-        if (i == 0) {
-            if (def->videos[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-                if (def->videos[i]->info.addr.pci.domain != 0 ||
-                    def->videos[i]->info.addr.pci.bus != 0 ||
-                    def->videos[i]->info.addr.pci.slot != 2 ||
-                    def->videos[i]->info.addr.pci.function != 0) {
-                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                                    _("Primary video card must have PCI address 0:0:2.0"));
-                    goto error;
-                }
-            } else {
-                def->videos[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
-                def->videos[i]->info.addr.pci.domain = 0;
-                def->videos[i]->info.addr.pci.bus = 0;
-                def->videos[i]->info.addr.pci.slot = 2;
-                def->videos[i]->info.addr.pci.function = 0;
-                if (qemuDomainPCIAddressReserveSlot(addrs, 2) < 0)
-                    goto error;
-            }
-        } else {
-            if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
-                continue;
-            if (qemuDomainPCIAddressSetNextAddr(addrs, &def->videos[i]->info) < 0)
-                goto error;
-        }
+    /* Start from 1, since first VGA was dealt with earlier */
+    for (i = 1; i < def->nvideos ; i++) {
+        if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+        if (qemuDomainPCIAddressSetNextAddr(addrs, &def->videos[i]->info) < 0)
+            goto error;
     }
     for (i = 0; i < def->ncontrollers ; i++) {
         /* FDC lives behind the ISA bridge */
         if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC)
             continue;
 
-        /* First IDE controller lives on the PIIX3 at slot=1, function=1 */
+        /* First IDE controller lives on the PIIX3 at slot=1, function=1,
+           dealt with earlier on*/
         if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE &&
-            def->controllers[i]->idx == 0) {
-            if (def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-                if (def->controllers[i]->info.addr.pci.domain != 0 ||
-                    def->controllers[i]->info.addr.pci.bus != 0 ||
-                    def->controllers[i]->info.addr.pci.slot != 1 ||
-                    def->controllers[i]->info.addr.pci.function != 1) {
-                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                                    _("Primary IDE controller must have PCI address 0:0:1.1"));
-                    goto error;
-                }
-            } else {
-                def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
-                def->controllers[i]->info.addr.pci.domain = 0;
-                def->controllers[i]->info.addr.pci.bus = 0;
-                def->controllers[i]->info.addr.pci.slot = 1;
-                def->controllers[i]->info.addr.pci.function = 1;
-                if (qemuDomainPCIAddressReserveSlot(addrs, 1) < 0)
-                    goto error;
-            }
-        } else {
-            if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
-                continue;
-            if (qemuDomainPCIAddressSetNextAddr(addrs, &def->controllers[i]->info) < 0)
-                goto error;
-        }
+            def->controllers[i]->idx == 0)
+            continue;
+
+        if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+        if (qemuDomainPCIAddressSetNextAddr(addrs, &def->controllers[i]->info) < 0)
+            goto error;
     }
     for (i = 0; i < def->ninputs ; i++) {
         /* Nada - none are PCI based (yet) */
-- 
1.7.1.1




More information about the libvir-list mailing list