render / rpms / libvirt

Forked from rpms/libvirt a year ago
Clone
6d3351
From a9c2a00aa4d4160f1057e2ce409558d244ec65f2 Mon Sep 17 00:00:00 2001
6d3351
Message-Id: <a9c2a00aa4d4160f1057e2ce409558d244ec65f2@dist-git>
6d3351
From: Andrea Bolognani <abologna@redhat.com>
6d3351
Date: Mon, 17 Jul 2017 12:09:10 +0200
6d3351
Subject: [PATCH] qemu: Automatically pick target index and model for pci-root
6d3351
 controllers
6d3351
6d3351
pSeries guests will soon need the new information; luckily,
6d3351
we can figure it out automatically most of the time, so
6d3351
users won't have to worry about it.
6d3351
6d3351
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
6d3351
Reviewed-by: Laine Stump <laine@laine.org>
6d3351
(cherry picked from commit 6e42d83f7ca2d2a481dde7d4cda85c5632759ee0)
6d3351
6d3351
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1431193
6d3351
6d3351
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
---
6d3351
 src/conf/domain_conf.c                             | 31 +++++++++
6d3351
 src/conf/domain_conf.h                             |  6 +-
6d3351
 src/libvirt_private.syms                           |  1 +
6d3351
 src/qemu/qemu_domain_address.c                     | 79 +++++++++++++++++++++-
6d3351
 .../qemuargv2xmldata/qemuargv2xml-pseries-disk.xml |  5 +-
6d3351
 .../qemuargv2xml-pseries-nvram.xml                 |  5 +-
6d3351
 .../qemuxml2xmlout-panic-pseries.xml               |  5 +-
6d3351
 .../qemuxml2xmlout-ppc64-usb-controller-legacy.xml |  5 +-
6d3351
 .../qemuxml2xmlout-ppc64-usb-controller.xml        |  5 +-
6d3351
 .../qemuxml2xmlout-pseries-nvram.xml               |  5 +-
6d3351
 .../qemuxml2xmlout-pseries-panic-missing.xml       |  5 +-
6d3351
 .../qemuxml2xmlout-pseries-panic-no-address.xml    |  5 +-
6d3351
 12 files changed, 145 insertions(+), 12 deletions(-)
6d3351
6d3351
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
6d3351
index 599db5cafe..86415964dc 100644
6d3351
--- a/src/conf/domain_conf.c
6d3351
+++ b/src/conf/domain_conf.c
6d3351
@@ -1881,6 +1881,37 @@ void virDomainControllerDefFree(virDomainControllerDefPtr def)
6d3351
     VIR_FREE(def);
6d3351
 }
6d3351
 
6d3351
+
6d3351
+/**
6d3351
+ * virDomainControllerIsPCIHostBridge:
6d3351
+ * @cont: controller
6d3351
+ *
6d3351
+ * Checks whether @cont is a PCI Host Bridge (PHB), a specific type
6d3351
+ * of PCI controller used by pSeries guests.
6d3351
+ *
6d3351
+ * Returns: true if @cont is a PHB, false otherwise.
6d3351
+ */
6d3351
+bool
6d3351
+virDomainControllerIsPCIHostBridge(const virDomainControllerDef *cont)
6d3351
+{
6d3351
+    virDomainControllerPCIModelName name;
6d3351
+
6d3351
+    /* PHBs are pci-root controllers */
6d3351
+    if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI ||
6d3351
+        cont->model != VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
6d3351
+        return false;
6d3351
+    }
6d3351
+
6d3351
+    name = cont->opts.pciopts.modelName;
6d3351
+
6d3351
+    /* The actual device used for PHBs is spapr-pci-host-bridge */
6d3351
+    if (name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE)
6d3351
+        return false;
6d3351
+
6d3351
+    return true;
6d3351
+}
6d3351
+
6d3351
+
6d3351
 virDomainFSDefPtr
6d3351
 virDomainFSDefNew(void)
6d3351
 {
6d3351
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
6d3351
index 50fdc6e2a6..f00c52c282 100644
6d3351
--- a/src/conf/domain_conf.h
6d3351
+++ b/src/conf/domain_conf.h
6d3351
@@ -2649,10 +2649,12 @@ int virDomainDeviceFindControllerModel(const virDomainDef *def,
6d3351
 virDomainDiskDefPtr virDomainDiskFindByBusAndDst(virDomainDefPtr def,
6d3351
                                                  int bus,
6d3351
                                                  char *dst);
6d3351
+
6d3351
+virDomainControllerDefPtr virDomainControllerDefNew(virDomainControllerType type);
6d3351
 void virDomainControllerDefFree(virDomainControllerDefPtr def);
6d3351
+bool virDomainControllerIsPCIHostBridge(const virDomainControllerDef *cont);
6d3351
+
6d3351
 virDomainFSDefPtr virDomainFSDefNew(void);
6d3351
-virDomainControllerDefPtr
6d3351
-virDomainControllerDefNew(virDomainControllerType type);
6d3351
 void virDomainFSDefFree(virDomainFSDefPtr def);
6d3351
 void virDomainActualNetDefFree(virDomainActualNetDefPtr def);
6d3351
 void virDomainNetDefClear(virDomainNetDefPtr def);
6d3351
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
6d3351
index 7876ffb208..04c9ff6120 100644
6d3351
--- a/src/libvirt_private.syms
6d3351
+++ b/src/libvirt_private.syms
6d3351
@@ -226,6 +226,7 @@ virDomainControllerFindByType;
6d3351
 virDomainControllerFindUnusedIndex;
6d3351
 virDomainControllerInsert;
6d3351
 virDomainControllerInsertPreAlloced;
6d3351
+virDomainControllerIsPCIHostBridge;
6d3351
 virDomainControllerModelPCITypeToString;
6d3351
 virDomainControllerModelSCSITypeFromString;
6d3351
 virDomainControllerModelSCSITypeToString;
6d3351
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
6d3351
index ff57edb564..626d30d477 100644
6d3351
--- a/src/qemu/qemu_domain_address.c
6d3351
+++ b/src/qemu/qemu_domain_address.c
6d3351
@@ -1843,6 +1843,7 @@ qemuDomainSupportsPCI(virDomainDefPtr def,
6d3351
 
6d3351
 static void
6d3351
 qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont,
6d3351
+                                           virDomainDefPtr def,
6d3351
                                            virQEMUCapsPtr qemuCaps)
6d3351
 {
6d3351
     int *modelName = &cont->opts.pciopts.modelName;
6d3351
@@ -1879,6 +1880,9 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont,
6d3351
         *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB_PCIE;
6d3351
         break;
6d3351
     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
6d3351
+        if (qemuDomainIsPSeries(def))
6d3351
+            *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE;
6d3351
+        break;
6d3351
     case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
6d3351
     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
6d3351
         break;
6d3351
@@ -1886,6 +1890,54 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont,
6d3351
 }
6d3351
 
6d3351
 
6d3351
+/**
6d3351
+ * qemuDomainAddressFindNewTargetIndex:
6d3351
+ * @def: domain definition
6d3351
+ *
6d3351
+ * Find a target index that can be used for a PCI controller.
6d3351
+ *
6d3351
+ * Returns: an unused target index, or -1 if all available target
6d3351
+ *          indexes are already taken.
6d3351
+ */
6d3351
+static int
6d3351
+qemuDomainAddressFindNewTargetIndex(virDomainDefPtr def)
6d3351
+{
6d3351
+    int targetIndex;
6d3351
+    int ret = -1;
6d3351
+
6d3351
+    /* Try all indexes between 1 and 31 - QEMU only supports 32
6d3351
+     * PHBs, and 0 is reserved for the default, implicit one */
6d3351
+    for (targetIndex = 1; targetIndex <= 31; targetIndex++) {
6d3351
+        bool found = false;
6d3351
+        size_t i;
6d3351
+
6d3351
+        for (i = 0; i < def->ncontrollers; i++) {
6d3351
+            virDomainControllerDefPtr cont = def->controllers[i];
6d3351
+
6d3351
+            /* Skip everything but PHBs */
6d3351
+            if (!virDomainControllerIsPCIHostBridge(cont))
6d3351
+                continue;
6d3351
+
6d3351
+            /* Stop looking as soon as we find a PHB that's
6d3351
+             * already using this specific target index */
6d3351
+            if (cont->opts.pciopts.targetIndex == targetIndex) {
6d3351
+                found = true;
6d3351
+                break;
6d3351
+            }
6d3351
+        }
6d3351
+
6d3351
+        /* If no existing PCI controller uses this index, great,
6d3351
+         * it means it's free and we can return it to the caller */
6d3351
+        if (!found) {
6d3351
+            ret = targetIndex;
6d3351
+            break;
6d3351
+        }
6d3351
+    }
6d3351
+
6d3351
+    return ret;
6d3351
+}
6d3351
+
6d3351
+
6d3351
 static int
6d3351
 qemuDomainAddressFindNewBusNr(virDomainDefPtr def)
6d3351
 {
6d3351
@@ -2146,7 +2198,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
6d3351
              * device in qemu) for any controller that doesn't yet
6d3351
              * have it set.
6d3351
              */
6d3351
-            qemuDomainPCIControllerSetDefaultModelName(cont, qemuCaps);
6d3351
+            qemuDomainPCIControllerSetDefaultModelName(cont, def, qemuCaps);
6d3351
 
6d3351
             /* set defaults for any other auto-generated config
6d3351
              * options for this controller that haven't been
6d3351
@@ -2183,9 +2235,32 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
6d3351
                     goto cleanup;
6d3351
                 }
6d3351
                 break;
6d3351
+            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
6d3351
+                if (!qemuDomainIsPSeries(def))
6d3351
+                    break;
6d3351
+                if (options->targetIndex == -1) {
6d3351
+                    if (cont->idx == 0) {
6d3351
+                        /* The pci-root controller with controller index 0
6d3351
+                         * must always be assigned target index 0, because
6d3351
+                         * it represents the implicit PHB which is treated
6d3351
+                         * differently than all other PHBs */
6d3351
+                        options->targetIndex = 0;
6d3351
+                    } else {
6d3351
+                        /* For all other PHBs the target index doesn't need
6d3351
+                         * to match the controller index or have any
6d3351
+                         * particular value, really */
6d3351
+                        options->targetIndex = qemuDomainAddressFindNewTargetIndex(def);
6d3351
+                    }
6d3351
+                }
6d3351
+                if (options->targetIndex == -1) {
6d3351
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
6d3351
+                                   _("No usable target index found for %d"),
6d3351
+                                   addr->bus);
6d3351
+                    goto cleanup;
6d3351
+                }
6d3351
+                break;
6d3351
             case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
6d3351
             case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
6d3351
-            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
6d3351
             case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
6d3351
             case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
6d3351
                 break;
6d3351
diff --git a/tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml b/tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml
6d3351
index 1bad8ee4c1..601d0f7f62 100644
6d3351
--- a/tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml
6d3351
+++ b/tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml
6d3351
@@ -30,7 +30,10 @@
6d3351
     <controller type='usb' index='0'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
6d3351
     </controller>
6d3351
-    <controller type='pci' index='0' model='pci-root'/>
6d3351
+    <controller type='pci' index='0' model='pci-root'>
6d3351
+      <model name='spapr-pci-host-bridge'/>
6d3351
+      <target index='0'/>
6d3351
+    </controller>
6d3351
     <controller type='scsi' index='0'>
6d3351
       <address type='spapr-vio' reg='0x2000'/>
6d3351
     </controller>
6d3351
diff --git a/tests/qemuargv2xmldata/qemuargv2xml-pseries-nvram.xml b/tests/qemuargv2xmldata/qemuargv2xml-pseries-nvram.xml
6d3351
index 7e9f8644fb..7787847a90 100644
6d3351
--- a/tests/qemuargv2xmldata/qemuargv2xml-pseries-nvram.xml
6d3351
+++ b/tests/qemuargv2xmldata/qemuargv2xml-pseries-nvram.xml
6d3351
@@ -17,7 +17,10 @@
6d3351
     <controller type='usb' index='0'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
6d3351
     </controller>
6d3351
-    <controller type='pci' index='0' model='pci-root'/>
6d3351
+    <controller type='pci' index='0' model='pci-root'>
6d3351
+      <model name='spapr-pci-host-bridge'/>
6d3351
+      <target index='0'/>
6d3351
+    </controller>
6d3351
     <memballoon model='none'/>
6d3351
     <nvram>
6d3351
       <address type='spapr-vio' reg='0x4000'/>
6d3351
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-panic-pseries.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-panic-pseries.xml
6d3351
index 1ed11ce12d..7fb49feb0f 100644
6d3351
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-panic-pseries.xml
6d3351
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-panic-pseries.xml
6d3351
@@ -17,7 +17,10 @@
6d3351
     <controller type='usb' index='0'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
6d3351
     </controller>
6d3351
-    <controller type='pci' index='0' model='pci-root'/>
6d3351
+    <controller type='pci' index='0' model='pci-root'>
6d3351
+      <model name='spapr-pci-host-bridge'/>
6d3351
+      <target index='0'/>
6d3351
+    </controller>
6d3351
     <serial type='pty'>
6d3351
       <target port='0'/>
6d3351
       <address type='spapr-vio' reg='0x30000000'/>
6d3351
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller-legacy.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller-legacy.xml
6d3351
index 33e7810072..6d3d51e7ee 100644
6d3351
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller-legacy.xml
6d3351
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller-legacy.xml
6d3351
@@ -22,7 +22,10 @@
6d3351
     <controller type='usb' index='0'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
6d3351
     </controller>
6d3351
-    <controller type='pci' index='0' model='pci-root'/>
6d3351
+    <controller type='pci' index='0' model='pci-root'>
6d3351
+      <model name='spapr-pci-host-bridge'/>
6d3351
+      <target index='0'/>
6d3351
+    </controller>
6d3351
     <memballoon model='virtio'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
6d3351
     </memballoon>
6d3351
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller.xml
6d3351
index 30932e5afd..659cabe327 100644
6d3351
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller.xml
6d3351
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller.xml
6d3351
@@ -22,7 +22,10 @@
6d3351
     <controller type='usb' index='0' model='pci-ohci'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
6d3351
     </controller>
6d3351
-    <controller type='pci' index='0' model='pci-root'/>
6d3351
+    <controller type='pci' index='0' model='pci-root'>
6d3351
+      <model name='spapr-pci-host-bridge'/>
6d3351
+      <target index='0'/>
6d3351
+    </controller>
6d3351
     <memballoon model='virtio'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
6d3351
     </memballoon>
6d3351
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-nvram.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-nvram.xml
6d3351
index 713f31c0e9..f89b23b338 100644
6d3351
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-nvram.xml
6d3351
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-nvram.xml
6d3351
@@ -17,7 +17,10 @@
6d3351
     <controller type='usb' index='0'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
6d3351
     </controller>
6d3351
-    <controller type='pci' index='0' model='pci-root'/>
6d3351
+    <controller type='pci' index='0' model='pci-root'>
6d3351
+      <model name='spapr-pci-host-bridge'/>
6d3351
+      <target index='0'/>
6d3351
+    </controller>
6d3351
     <memballoon model='none'/>
6d3351
     <nvram>
6d3351
       <address type='spapr-vio' reg='0x4000'/>
6d3351
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-missing.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-missing.xml
6d3351
index 1ed11ce12d..7fb49feb0f 100644
6d3351
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-missing.xml
6d3351
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-missing.xml
6d3351
@@ -17,7 +17,10 @@
6d3351
     <controller type='usb' index='0'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
6d3351
     </controller>
6d3351
-    <controller type='pci' index='0' model='pci-root'/>
6d3351
+    <controller type='pci' index='0' model='pci-root'>
6d3351
+      <model name='spapr-pci-host-bridge'/>
6d3351
+      <target index='0'/>
6d3351
+    </controller>
6d3351
     <serial type='pty'>
6d3351
       <target port='0'/>
6d3351
       <address type='spapr-vio' reg='0x30000000'/>
6d3351
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-no-address.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-no-address.xml
6d3351
index 1ed11ce12d..7fb49feb0f 100644
6d3351
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-no-address.xml
6d3351
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-no-address.xml
6d3351
@@ -17,7 +17,10 @@
6d3351
     <controller type='usb' index='0'>
6d3351
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
6d3351
     </controller>
6d3351
-    <controller type='pci' index='0' model='pci-root'/>
6d3351
+    <controller type='pci' index='0' model='pci-root'>
6d3351
+      <model name='spapr-pci-host-bridge'/>
6d3351
+      <target index='0'/>
6d3351
+    </controller>
6d3351
     <serial type='pty'>
6d3351
       <target port='0'/>
6d3351
       <address type='spapr-vio' reg='0x30000000'/>
6d3351
-- 
6d3351
2.13.3
6d3351