7a3408
From 12305284ccf9163e90fbfc9b2c14ac735796e781 Mon Sep 17 00:00:00 2001
7a3408
Message-Id: <12305284ccf9163e90fbfc9b2c14ac735796e781@dist-git>
7a3408
From: Andrea Bolognani <abologna@redhat.com>
7a3408
Date: Tue, 11 Aug 2015 17:16:09 +0200
7a3408
Subject: [PATCH] cpu: Implement backwards compatibility in the ppc64 driver
7a3408
7a3408
All previously recognized CPU models (POWER7_v2.1, POWER7_v2.3,
7a3408
POWER7+_v2.1 and POWER8_v1.0) are internally converted to the
7a3408
corrisponding generation name so that existing guests don't stop
7a3408
working.
7a3408
7a3408
(cherry picked from commit dee2247afa78c66db737626acb30afe04bd7cdef)
7a3408
7a3408
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1250977
7a3408
7a3408
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
7a3408
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7a3408
---
7a3408
 src/cpu/cpu_ppc64.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
7a3408
 1 file changed, 45 insertions(+), 2 deletions(-)
7a3408
7a3408
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
7a3408
index fafd84c..f24fc41 100644
7a3408
--- a/src/cpu/cpu_ppc64.c
7a3408
+++ b/src/cpu/cpu_ppc64.c
7a3408
@@ -57,6 +57,33 @@ struct ppc64_map {
7a3408
     struct ppc64_model *models;
7a3408
 };
7a3408
 
7a3408
+/* Convert a legacy CPU definition by transforming
7a3408
+ * model names to generation names:
7a3408
+ *   POWER7_v2.1  => POWER7
7a3408
+ *   POWER7_v2.3  => POWER7
7a3408
+ *   POWER7+_v2.1 => POWER7
7a3408
+ *   POWER8_v1.0  => POWER8 */
7a3408
+static virCPUDefPtr
7a3408
+ppc64ConvertLegacyCPUDef(const virCPUDef *legacy)
7a3408
+{
7a3408
+    virCPUDefPtr cpu;
7a3408
+
7a3408
+    if (!(cpu = virCPUDefCopy(legacy)))
7a3408
+        goto out;
7a3408
+
7a3408
+    if (!(STREQ(cpu->model, "POWER7_v2.1") ||
7a3408
+          STREQ(cpu->model, "POWER7_v2.3") ||
7a3408
+          STREQ(cpu->model, "POWER7+_v2.1") ||
7a3408
+          STREQ(cpu->model, "POWER8_v1.0"))) {
7a3408
+        goto out;
7a3408
+    }
7a3408
+
7a3408
+    cpu->model[strlen("POWERx")] = 0;
7a3408
+
7a3408
+ out:
7a3408
+    return cpu;
7a3408
+}
7a3408
+
7a3408
 static void
7a3408
 ppc64DataFree(virCPUppc64Data *data)
7a3408
 {
7a3408
@@ -424,18 +451,22 @@ ppc64MakeCPUData(virArch arch,
7a3408
 
7a3408
 static virCPUCompareResult
7a3408
 ppc64Compute(virCPUDefPtr host,
7a3408
-             const virCPUDef *cpu,
7a3408
+             const virCPUDef *other,
7a3408
              virCPUDataPtr *guestData,
7a3408
              char **message)
7a3408
 {
7a3408
     struct ppc64_map *map = NULL;
7a3408
     struct ppc64_model *host_model = NULL;
7a3408
     struct ppc64_model *guest_model = NULL;
7a3408
-
7a3408
+    virCPUDefPtr cpu = NULL;
7a3408
     virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
7a3408
     virArch arch;
7a3408
     size_t i;
7a3408
 
7a3408
+    /* Ensure existing configurations are handled correctly */
7a3408
+    if (!(cpu = ppc64ConvertLegacyCPUDef(other)))
7a3408
+        goto cleanup;
7a3408
+
7a3408
     if (cpu->arch != VIR_ARCH_NONE) {
7a3408
         bool found = false;
7a3408
 
7a3408
@@ -504,6 +535,7 @@ ppc64Compute(virCPUDefPtr host,
7a3408
     ret = VIR_CPU_COMPARE_IDENTICAL;
7a3408
 
7a3408
  cleanup:
7a3408
+    virCPUDefFree(cpu);
7a3408
     ppc64MapFree(map);
7a3408
     ppc64ModelFree(host_model);
7a3408
     ppc64ModelFree(guest_model);
7a3408
@@ -681,6 +713,17 @@ ppc64DriverBaseline(virCPUDefPtr *cpus,
7a3408
     for (i = 0; i < ncpus; i++) {
7a3408
         const struct ppc64_vendor *vnd;
7a3408
 
7a3408
+        /* Hosts running old (<= 1.2.18) versions of libvirt will report
7a3408
+         * strings like 'power7+' or 'power8e' instead of proper CPU model
7a3408
+         * names in the capabilities XML; moreover, they lack information
7a3408
+         * about some proper CPU models like 'POWER8'.
7a3408
+         * This implies two things:
7a3408
+         *   1) baseline among such hosts never worked
7a3408
+         *   2) while a few models, eg. 'POWER8_v1.0', could work on both
7a3408
+         *      old and new versions of libvirt, the information we have
7a3408
+         *      here is not enough to pick such a model
7a3408
+         * Hence we just compare models by name to decide whether or not
7a3408
+         * two hosts are compatible */
7a3408
         if (STRNEQ(cpus[i]->model, model->name)) {
7a3408
             virReportError(VIR_ERR_OPERATION_FAILED, "%s",
7a3408
                            _("CPUs are incompatible"));
7a3408
-- 
7a3408
2.5.0
7a3408