]> xenbits.xensource.com Git - libvirt.git/commitdiff
cpu: Introduce virCPUConvertLegacy API
authorJiri Denemark <jdenemar@redhat.com>
Wed, 9 Nov 2016 16:09:48 +0000 (17:09 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 15 Nov 2016 14:49:16 +0000 (15:49 +0100)
PPC driver needs to convert POWERx_v* legacy CPU model names into POWERx
to maintain backward compatibility with existing domains. This patch
adds a new step into the guest CPU configuration work flow which CPU
drivers can use to convert legacy CPU definitions.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
src/cpu/cpu.c
src/cpu/cpu.h
src/cpu/cpu_ppc64.c
src/libvirt_private.syms
src/qemu/qemu_process.c
tests/cputest.c

index 9d34206bf51bf7c6caafbcea83ac1da66e072fd4..4a5fbb1fde94f93d6135e484765aa5946d8959d3 100644 (file)
@@ -934,3 +934,38 @@ virCPUTranslate(virArch arch,
     VIR_DEBUG("model=%s", NULLSTR(cpu->model));
     return 0;
 }
+
+
+/**
+ * virCPUConvertLegacy:
+ *
+ * @arch: CPU architecture
+ * @cpu: CPU definition to be converted
+ *
+ * Convert legacy CPU definition into one that the corresponding cpu driver
+ * will be able to work with. Currently this is only implemented by the PPC
+ * driver, which needs to convert legacy POWERx_v* names into POWERx.
+ *
+ * Returns -1 on error, 0 on success.
+ */
+int
+virCPUConvertLegacy(virArch arch,
+                    virCPUDefPtr cpu)
+{
+    struct cpuArchDriver *driver;
+
+    VIR_DEBUG("arch=%s, cpu=%p, model=%s",
+              virArchToString(arch), cpu, NULLSTR(cpu->model));
+
+    if (!(driver = cpuGetSubDriver(arch)))
+        return -1;
+
+    if (!driver->convertLegacy)
+        return 0;
+
+    if (driver->convertLegacy(cpu) < 0)
+        return -1;
+
+    VIR_DEBUG("model=%s", NULLSTR(cpu->model));
+    return 0;
+}
index 5ad811270ebd55e73e04f301d520e65f386b03b6..ff48fb5ca2e8cedc55ebb6c393f23903766299cc 100644 (file)
@@ -112,6 +112,9 @@ typedef int
                        const char **models,
                        unsigned int nmodels);
 
+typedef int
+(*virCPUArchConvertLegacy)(virCPUDefPtr cpu);
+
 struct cpuArchDriver {
     const char *name;
     const virArch *arch;
@@ -130,6 +133,7 @@ struct cpuArchDriver {
     virCPUArchDataParse dataParse;
     virCPUArchGetModels getModels;
     virCPUArchTranslate translate;
+    virCPUArchConvertLegacy convertLegacy;
 };
 
 
@@ -229,6 +233,10 @@ virCPUTranslate(virArch arch,
                 unsigned int nmodels)
     ATTRIBUTE_NONNULL(2);
 
+int
+virCPUConvertLegacy(virArch arch,
+                    virCPUDefPtr cpu)
+    ATTRIBUTE_NONNULL(2);
 
 /* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and
  * have no real-life usage
index bdb026b2c28191f4d97d8b379569d429f77aadb5..8b71ef55f2a9a016004ed6146afd058ef6f5d6c4 100644 (file)
@@ -63,26 +63,18 @@ struct ppc64_map {
  *   POWER7_v2.3  => POWER7
  *   POWER7+_v2.1 => POWER7
  *   POWER8_v1.0  => POWER8 */
-static virCPUDefPtr
-ppc64ConvertLegacyCPUDef(const virCPUDef *legacy)
+static int
+virCPUppc64ConvertLegacy(virCPUDefPtr cpu)
 {
-    virCPUDefPtr cpu;
-
-    if (!(cpu = virCPUDefCopy(legacy)))
-        goto out;
-
-    if (!cpu->model ||
-        !(STREQ(cpu->model, "POWER7_v2.1") ||
-          STREQ(cpu->model, "POWER7_v2.3") ||
-          STREQ(cpu->model, "POWER7+_v2.1") ||
-          STREQ(cpu->model, "POWER8_v1.0"))) {
-        goto out;
+    if (cpu->model &&
+        (STREQ(cpu->model, "POWER7_v2.1") ||
+         STREQ(cpu->model, "POWER7_v2.3") ||
+         STREQ(cpu->model, "POWER7+_v2.1") ||
+         STREQ(cpu->model, "POWER8_v1.0"))) {
+        cpu->model[strlen("POWERx")] = 0;
     }
 
-    cpu->model[strlen("POWERx")] = 0;
-
- out:
-    return cpu;
+    return 0;
 }
 
 /* Some hosts can run guests in compatibility mode, but not all
@@ -519,7 +511,8 @@ ppc64Compute(virCPUDefPtr host,
     size_t i;
 
     /* Ensure existing configurations are handled correctly */
-    if (!(cpu = ppc64ConvertLegacyCPUDef(other)))
+    if (!(cpu = virCPUDefCopy(other)) ||
+        virCPUppc64ConvertLegacy(cpu) < 0)
         goto cleanup;
 
     if (cpu->arch != VIR_ARCH_NONE) {
@@ -922,4 +915,5 @@ struct cpuArchDriver cpuDriverPPC64 = {
     .baseline   = ppc64DriverBaseline,
     .update     = virCPUppc64Update,
     .getModels  = virCPUppc64DriverGetModels,
+    .convertLegacy = virCPUppc64ConvertLegacy,
 };
index 41b674d6e5fcac929410aa95f16dbe65ceaa5f0b..38f8ecb631db13b6b6e3aa820429d852ce668305 100644 (file)
@@ -983,6 +983,7 @@ cpuNodeData;
 virCPUCheckFeature;
 virCPUCompare;
 virCPUCompareXML;
+virCPUConvertLegacy;
 virCPUDataCheckFeature;
 virCPUDataFormat;
 virCPUDataParse;
index 14c799e46f5a556bb5cb0dda532ab419d66531e4..3552a3130eeda27a5df6993e19b97cfb46348422 100644 (file)
@@ -5066,6 +5066,9 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
         return -1;
     }
 
+    if (virCPUConvertLegacy(caps->host.arch, def->cpu) < 0)
+        return -1;
+
     /* nothing to update for host-passthrough */
     if (def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
         return 0;
index 1d7f6bc56243b01a3b24ab1a23d93f09ea0a3c9c..8612e920ee8a0ead2c0bb22a53651d232e5233fc 100644 (file)
@@ -251,6 +251,9 @@ cpuTestGuestCPU(const void *arg)
         !(cpu = cpuTestLoadXML(data->arch, data->name)))
         goto cleanup;
 
+    if (virCPUConvertLegacy(host->arch, cpu) < 0)
+        goto cleanup;
+
     cmpResult = virCPUCompare(host->arch, host, cpu, false);
     if (cmpResult == VIR_CPU_COMPARE_ERROR ||
         cmpResult == VIR_CPU_COMPARE_INCOMPATIBLE) {
@@ -794,7 +797,7 @@ mymain(void)
 
     DO_TEST_GUESTCPU("ppc64", "host", "guest", ppc_models, 0);
     DO_TEST_GUESTCPU("ppc64", "host", "guest-nofallback", ppc_models, -1);
-    DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy", ppc_models, /*0*/ -1);
+    DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy", ppc_models, 0);
     DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy-incompatible", ppc_models, -1);
     DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy-invalid", ppc_models, -1);