]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Automatically pick target index and model for pci-root controllers
authorAndrea Bolognani <abologna@redhat.com>
Tue, 28 Feb 2017 13:58:33 +0000 (14:58 +0100)
committerAndrea Bolognani <abologna@redhat.com>
Sat, 15 Jul 2017 12:50:42 +0000 (14:50 +0200)
pSeries guests will soon need the new information; luckily,
we can figure it out automatically most of the time, so
users won't have to worry about it.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Laine Stump <laine@laine.org>
12 files changed:
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_domain_address.c
tests/qemuargv2xmldata/qemuargv2xml-pseries-disk.xml
tests/qemuargv2xmldata/qemuargv2xml-pseries-nvram.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-panic-pseries.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller-legacy.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-ppc64-usb-controller.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-nvram.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-missing.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-panic-no-address.xml

index 5dd1824701953b5ea5aba64a2cd75c45f54659ff..3feeccb9f0520e6c6b5236c57a905cf56ca0f975 100644 (file)
@@ -1899,6 +1899,37 @@ void virDomainControllerDefFree(virDomainControllerDefPtr def)
     VIR_FREE(def);
 }
 
+
+/**
+ * virDomainControllerIsPCIHostBridge:
+ * @cont: controller
+ *
+ * Checks whether @cont is a PCI Host Bridge (PHB), a specific type
+ * of PCI controller used by pSeries guests.
+ *
+ * Returns: true if @cont is a PHB, false otherwise.
+ */
+bool
+virDomainControllerIsPCIHostBridge(const virDomainControllerDef *cont)
+{
+    virDomainControllerPCIModelName name;
+
+    /* PHBs are pci-root controllers */
+    if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI ||
+        cont->model != VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
+        return false;
+    }
+
+    name = cont->opts.pciopts.modelName;
+
+    /* The actual device used for PHBs is spapr-pci-host-bridge */
+    if (name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE)
+        return false;
+
+    return true;
+}
+
+
 virDomainFSDefPtr
 virDomainFSDefNew(void)
 {
index 6e3608f24ba3a9fa680c750b0915b6272423086f..af15ee8b516ebdb57ad6e94e5b173a03685f1d5e 100644 (file)
@@ -2678,10 +2678,12 @@ int virDomainDeviceFindControllerModel(const virDomainDef *def,
 virDomainDiskDefPtr virDomainDiskFindByBusAndDst(virDomainDefPtr def,
                                                  int bus,
                                                  char *dst);
+
+virDomainControllerDefPtr virDomainControllerDefNew(virDomainControllerType type);
 void virDomainControllerDefFree(virDomainControllerDefPtr def);
+bool virDomainControllerIsPCIHostBridge(const virDomainControllerDef *cont);
+
 virDomainFSDefPtr virDomainFSDefNew(void);
-virDomainControllerDefPtr
-virDomainControllerDefNew(virDomainControllerType type);
 void virDomainFSDefFree(virDomainFSDefPtr def);
 void virDomainActualNetDefFree(virDomainActualNetDefPtr def);
 void virDomainNetDefClear(virDomainNetDefPtr def);
index 5d30090646503e59df5dfbc5225fc7b8e97b5fd8..237162c095e748b1089647f31fa43d6bf66af0c3 100644 (file)
@@ -226,6 +226,7 @@ virDomainControllerFindByType;
 virDomainControllerFindUnusedIndex;
 virDomainControllerInsert;
 virDomainControllerInsertPreAlloced;
+virDomainControllerIsPCIHostBridge;
 virDomainControllerModelPCITypeToString;
 virDomainControllerModelSCSITypeFromString;
 virDomainControllerModelSCSITypeToString;
index efc698da13433b2c1cbcdd03045054025e653d0b..bea95da444a0ad73dfc328532b95630ec9bcd1e4 100644 (file)
@@ -1848,6 +1848,7 @@ qemuDomainSupportsPCI(virDomainDefPtr def,
 
 static void
 qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont,
+                                           virDomainDefPtr def,
                                            virQEMUCapsPtr qemuCaps)
 {
     int *modelName = &cont->opts.pciopts.modelName;
@@ -1884,6 +1885,9 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont,
         *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB_PCIE;
         break;
     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+        if (qemuDomainIsPSeries(def))
+            *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE;
+        break;
     case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
         break;
@@ -1891,6 +1895,54 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont,
 }
 
 
+/**
+ * qemuDomainAddressFindNewTargetIndex:
+ * @def: domain definition
+ *
+ * Find a target index that can be used for a PCI controller.
+ *
+ * Returns: an unused target index, or -1 if all available target
+ *          indexes are already taken.
+ */
+static int
+qemuDomainAddressFindNewTargetIndex(virDomainDefPtr def)
+{
+    int targetIndex;
+    int ret = -1;
+
+    /* Try all indexes between 1 and 31 - QEMU only supports 32
+     * PHBs, and 0 is reserved for the default, implicit one */
+    for (targetIndex = 1; targetIndex <= 31; targetIndex++) {
+        bool found = false;
+        size_t i;
+
+        for (i = 0; i < def->ncontrollers; i++) {
+            virDomainControllerDefPtr cont = def->controllers[i];
+
+            /* Skip everything but PHBs */
+            if (!virDomainControllerIsPCIHostBridge(cont))
+                continue;
+
+            /* Stop looking as soon as we find a PHB that's
+             * already using this specific target index */
+            if (cont->opts.pciopts.targetIndex == targetIndex) {
+                found = true;
+                break;
+            }
+        }
+
+        /* If no existing PCI controller uses this index, great,
+         * it means it's free and we can return it to the caller */
+        if (!found) {
+            ret = targetIndex;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
 static int
 qemuDomainAddressFindNewBusNr(virDomainDefPtr def)
 {
@@ -2151,7 +2203,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
              * device in qemu) for any controller that doesn't yet
              * have it set.
              */
-            qemuDomainPCIControllerSetDefaultModelName(cont, qemuCaps);
+            qemuDomainPCIControllerSetDefaultModelName(cont, def, qemuCaps);
 
             /* set defaults for any other auto-generated config
              * options for this controller that haven't been
@@ -2188,9 +2240,32 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
                     goto cleanup;
                 }
                 break;
+            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+                if (!qemuDomainIsPSeries(def))
+                    break;
+                if (options->targetIndex == -1) {
+                    if (cont->idx == 0) {
+                        /* The pci-root controller with controller index 0
+                         * must always be assigned target index 0, because
+                         * it represents the implicit PHB which is treated
+                         * differently than all other PHBs */
+                        options->targetIndex = 0;
+                    } else {
+                        /* For all other PHBs the target index doesn't need
+                         * to match the controller index or have any
+                         * particular value, really */
+                        options->targetIndex = qemuDomainAddressFindNewTargetIndex(def);
+                    }
+                }
+                if (options->targetIndex == -1) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("No usable target index found for %d"),
+                                   addr->bus);
+                    goto cleanup;
+                }
+                break;
             case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
             case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
-            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
             case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
             case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
                 break;
index 1bad8ee4c13b7e5203f5bd8f6d85b0e12e6ef13e..601d0f7f62535d2f3d714a260d8aa9cd06bf2190 100644 (file)
     <controller type='usb' index='0'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
     </controller>
-    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='pci' index='0' model='pci-root'>
+      <model name='spapr-pci-host-bridge'/>
+      <target index='0'/>
+    </controller>
     <controller type='scsi' index='0'>
       <address type='spapr-vio' reg='0x2000'/>
     </controller>
index 7e9f8644fb9b22600987ad193ae33a8f4c9eec34..7787847a903fcb7dea2c27999eea385dda48b5c0 100644 (file)
     <controller type='usb' index='0'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
     </controller>
-    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='pci' index='0' model='pci-root'>
+      <model name='spapr-pci-host-bridge'/>
+      <target index='0'/>
+    </controller>
     <memballoon model='none'/>
     <nvram>
       <address type='spapr-vio' reg='0x4000'/>
index 1ed11ce12d6e498ca61ca182fde8d29a54298fb5..7fb49feb0f382ac779272fed2c826064f4f948ca 100644 (file)
     <controller type='usb' index='0'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
     </controller>
-    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='pci' index='0' model='pci-root'>
+      <model name='spapr-pci-host-bridge'/>
+      <target index='0'/>
+    </controller>
     <serial type='pty'>
       <target port='0'/>
       <address type='spapr-vio' reg='0x30000000'/>
index b7bde241dc85a0fe3a013bca0d11eca381ae81f0..673b81dbc9bc1253106ba2e5cc365a6e2ef468a4 100644 (file)
     <controller type='usb' index='0'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
     </controller>
-    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='pci' index='0' model='pci-root'>
+      <model name='spapr-pci-host-bridge'/>
+      <target index='0'/>
+    </controller>
     <memballoon model='virtio'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
     </memballoon>
index 82aaaca721ab9ae7f30703f5b9dab36d55a734f7..68995a9ce0cdada94966bbf20c6fc5daf0c2a022 100644 (file)
     <controller type='usb' index='0' model='pci-ohci'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
     </controller>
-    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='pci' index='0' model='pci-root'>
+      <model name='spapr-pci-host-bridge'/>
+      <target index='0'/>
+    </controller>
     <memballoon model='virtio'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
     </memballoon>
index 713f31c0e946e6845d1eff093ca856b24af509fb..f89b23b3387454c3ccb5c7b38940139a5bd04741 100644 (file)
     <controller type='usb' index='0'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
     </controller>
-    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='pci' index='0' model='pci-root'>
+      <model name='spapr-pci-host-bridge'/>
+      <target index='0'/>
+    </controller>
     <memballoon model='none'/>
     <nvram>
       <address type='spapr-vio' reg='0x4000'/>
index 1ed11ce12d6e498ca61ca182fde8d29a54298fb5..7fb49feb0f382ac779272fed2c826064f4f948ca 100644 (file)
     <controller type='usb' index='0'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
     </controller>
-    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='pci' index='0' model='pci-root'>
+      <model name='spapr-pci-host-bridge'/>
+      <target index='0'/>
+    </controller>
     <serial type='pty'>
       <target port='0'/>
       <address type='spapr-vio' reg='0x30000000'/>
index 1ed11ce12d6e498ca61ca182fde8d29a54298fb5..7fb49feb0f382ac779272fed2c826064f4f948ca 100644 (file)
     <controller type='usb' index='0'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
     </controller>
-    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='pci' index='0' model='pci-root'>
+      <model name='spapr-pci-host-bridge'/>
+      <target index='0'/>
+    </controller>
     <serial type='pty'>
       <target port='0'/>
       <address type='spapr-vio' reg='0x30000000'/>