]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Fix pci bus naming for PPC
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 23 Apr 2014 15:35:37 +0000 (16:35 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 24 Apr 2014 13:21:39 +0000 (14:21 +0100)
Recent discussions around naming of 'pci' vs 'pci.0' for PPC
made me go back and look at the PPC emulator in every historical
version of QEMU since 1.0. The results were worse than I imagined.
This patch adds the logic required to make libvirt work with PPC
correctly with naming variations across all versions & machine
types.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_command.c

index a5c6879d616fa05f3c02c767b84012ec4d7d6b7d..b491f58fe1a234f554fa37746cdfcdaff1093b76 100644 (file)
@@ -1928,6 +1928,56 @@ virQEMUCapsGet(virQEMUCapsPtr qemuCaps,
 }
 
 
+bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps,
+                               virDomainDefPtr def)
+{
+    bool hasMultiBus = virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS);
+
+    if (hasMultiBus)
+        return true;
+
+    if (def->os.arch == VIR_ARCH_PPC ||
+        def->os.arch == VIR_ARCH_PPC64) {
+        /*
+         * Usage of pci.0 naming:
+         *
+         *    ref405ep: no pci
+         *       taihu: no pci
+         *      bamboo: 1.1.0
+         *       mac99: 2.0.0
+         *     g3beige: 2.0.0
+         *        prep: 1.4.0
+         *     pseries: 2.0.0
+         *   mpc8544ds: forever
+         * virtex-m507: no pci
+         *     ppce500: 1.6.0
+         */
+
+        if (qemuCaps->version >= 2000000)
+            return true;
+
+        if (qemuCaps->version >= 1006000 &&
+            STREQ(def->os.machine, "ppce500"))
+            return true;
+
+        if (qemuCaps->version >= 1004000 &&
+            STREQ(def->os.machine, "prep"))
+            return true;
+
+        if (qemuCaps->version >= 1001000 &&
+            STREQ(def->os.machine, "bamboo"))
+            return true;
+
+        if (STREQ(def->os.machine, "mpc8544ds"))
+            return true;
+
+        return false;
+    }
+
+    return false;
+}
+
+
 const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps)
 {
     return qemuCaps->binary;
@@ -2809,15 +2859,22 @@ virQEMUCapsInitHelp(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid)
                                 false) < 0)
         goto cleanup;
 
-    /* Currently only x86_64 and i686 support PCI-multibus. */
+    /* x86_64 and i686 support PCI-multibus on all machine types
+     * since forever. For other architectures, it has been changing
+     * across releases, per machine type, so we can't simply detect
+     * it here. Thus the rest of the logic is provided in a separate
+     * helper virQEMUCapsHasPCIMultiBus() which keys off the machine
+     * stored in virDomainDef and QEMU version number
+     */
     if (qemuCaps->arch == VIR_ARCH_X86_64 ||
-        qemuCaps->arch == VIR_ARCH_I686) {
+        qemuCaps->arch == VIR_ARCH_I686)
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS);
-    } else {
-        /* -no-acpi is not supported on other archs
-         * even if qemu reports it in -help */
+
+    /* -no-acpi is not supported on non-x86
+     * even if qemu reports it in -help */
+    if (qemuCaps->arch != VIR_ARCH_X86_64 &&
+        qemuCaps->arch != VIR_ARCH_I686)
         virQEMUCapsClear(qemuCaps, QEMU_CAPS_NO_ACPI);
-    }
 
     /* virQEMUCapsExtractDeviceStr will only set additional caps if qemu
      * understands the 0.13.0+ notion of "-device driver,".  */
@@ -2934,9 +2991,14 @@ virQEMUCapsInitArchQMPBasic(virQEMUCapsPtr qemuCaps,
         goto cleanup;
     }
 
-    /*
-     * Currently only x86_64 and i686 support PCI-multibus,
-     * -no-acpi and -no-kvm-pit-reinjection.
+    /* x86_64 and i686 support PCI-multibus on all machine types
+     * since forever. For other architectures, it has been changing
+     * across releases, per machine type, so we can't simply detect
+     * it here. Thus the rest of the logic is provided in a separate
+     * helper virQEMUCapsHasPCIMultiBus() which keys off the machine
+     * stored in virDomainDef and QEMU version number
+     *
+     * ACPI/HPET/KVM PIT are also x86 specific
      */
     if (qemuCaps->arch == VIR_ARCH_X86_64 ||
         qemuCaps->arch == VIR_ARCH_I686) {
index df8c978546cae5a12bc11213983d78816b65e265..5c63b817f12d0ad1c2240485ee991930467270e3 100644 (file)
@@ -239,6 +239,9 @@ void virQEMUCapsClear(virQEMUCapsPtr qemuCaps,
 bool virQEMUCapsGet(virQEMUCapsPtr qemuCaps,
                     enum virQEMUCapsFlags flag);
 
+bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps,
+                               virDomainDefPtr def);
+
 char *virQEMUCapsFlagsString(virQEMUCapsPtr qemuCaps);
 
 const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps);
index 91367ab38f11f05e8b76fcf69b0729860a8973df..403c9a9d3b86ea66fd8ead0a5888613792d733ee 100644 (file)
@@ -3076,7 +3076,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
                 goto cleanup;
             }
         } else {
-            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS)) {
+            if (virQEMUCapsHasPCIMultiBus(qemuCaps, domainDef)) {
                 virBufferAsprintf(buf, ",bus=%s", contAlias);
             } else {
                 virBufferAddLit(buf, ",bus=pci");