[libvirt] [PATCH 5/8] cpu: Reimplement PowerPCBaseline

Jiri Denemark jdenemar at redhat.com
Fri Dec 21 00:01:54 UTC 2012


Baseline API is supposed to return guest CPU definition that can be used
on any of the provided host CPUs. Since PowerPC CPUs are either
identical or incompatible, the API just needs to check that all provided
CPUs are identical. Previous implementation was completely bogus.

The function is also renamed as ppcBaseline to match other functions in
PowerPC CPU driver.
---
 src/cpu/cpu_powerpc.c | 130 +++++++++++++++++++++++---------------------------
 1 file changed, 61 insertions(+), 69 deletions(-)

diff --git a/src/cpu/cpu_powerpc.c b/src/cpu/cpu_powerpc.c
index 3fa98bd..3722fc0 100644
--- a/src/cpu/cpu_powerpc.c
+++ b/src/cpu/cpu_powerpc.c
@@ -360,47 +360,6 @@ error:
     return NULL;
 }
 
-static struct ppc_model *
-ppcModelCopy(const struct ppc_model *model)
-{
-    struct ppc_model *copy;
-
-    if (VIR_ALLOC(copy) < 0
-        || VIR_ALLOC(copy->data) < 0
-        || !(copy->name = strdup(model->name))){
-        ppcModelFree(copy);
-        return NULL;
-    }
-
-    copy->data->ppc.pvr = model->data->ppc.pvr;
-    copy->vendor = model->vendor;
-
-    return copy;
-}
-
-static struct ppc_model *
-ppcModelFromCPU(const virCPUDefPtr cpu,
-                const struct ppc_map *map)
-{
-    struct ppc_model *model = NULL;
-
-    if ((model = ppcModelFind(map, cpu->model))) {
-        if ((model = ppcModelCopy(model)) == NULL) {
-            goto no_memory;
-        }
-    } else if (!(model = ppcModelNew())) {
-        goto no_memory;
-    }
-
-    return model;
-
-no_memory:
-    virReportOOMError();
-    ppcModelFree(model);
-
-    return NULL;
-}
-
 static virCPUCompareResult
 ppcCompare(virCPUDefPtr host,
            virCPUDefPtr cpu)
@@ -548,56 +507,89 @@ PowerPCUpdate(virCPUDefPtr guest ATTRIBUTE_UNUSED,
    return 0;
 }
 static virCPUDefPtr
-PowerPCBaseline(virCPUDefPtr *cpus,
-                unsigned int ncpus ATTRIBUTE_UNUSED,
-                const char **models ATTRIBUTE_UNUSED,
-                unsigned int nmodels ATTRIBUTE_UNUSED)
+ppcBaseline(virCPUDefPtr *cpus,
+            unsigned int ncpus,
+            const char **models,
+            unsigned int nmodels)
 {
     struct ppc_map *map = NULL;
-    struct ppc_model *base_model = NULL;
+    const struct ppc_model *model;
+    const struct ppc_vendor *vendor = NULL;
     virCPUDefPtr cpu = NULL;
-    struct ppc_model *model = NULL;
-    bool outputModel = true;
+    unsigned int i;
+
+    if (!(map = ppcLoadMap()))
+        goto error;
 
-    if (!(map = ppcLoadMap())) {
+    if (!(model = ppcModelFind(map, cpus[0]->model))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Unknown CPU model %s"), cpus[0]->model);
         goto error;
     }
 
-    if (!(base_model = ppcModelFromCPU(cpus[0], map))) {
+    if (!cpuModelIsAllowed(model->name, models, nmodels)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                        _("CPU model %s is not supported by hypervisor"),
+                        model->name);
         goto error;
     }
 
-    if (VIR_ALLOC(cpu) < 0)
-         goto no_memory;
+    for (i = 0; i < ncpus; i++) {
+        const struct ppc_vendor *vnd;
 
-    cpu->arch = cpus[0]->arch;
-    cpu->type = VIR_CPU_TYPE_GUEST;
-    cpu->match = VIR_CPU_MATCH_EXACT;
+        if (STRNEQ(cpus[i]->model, model->name)) {
+            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                           _("CPUs are incompatible"));
+            goto error;
+        }
 
-    if (!cpus[0]->model) {
-        outputModel = false;
-    } else if (!(model = ppcModelFind(map, cpus[0]->model))) {
-        virReportError(VIR_ERR_OPERATION_FAILED,
-                       _("Unknown CPU vendor %s"), cpus[0]->model);
-        goto error;
+        if (!cpus[i]->vendor)
+            continue;
+
+        if (!(vnd = ppcVendorFind(map, cpus[i]->vendor))) {
+            virReportError(VIR_ERR_OPERATION_FAILED,
+                           _("Unknown CPU vendor %s"), cpus[i]->vendor);
+            goto error;
+        }
+
+        if (model->vendor) {
+            if (model->vendor != vnd) {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                               _("CPU vendor %s of model %s differs from "
+                                 "vendor %s"),
+                               model->vendor->name, model->name,
+                               vnd->name);
+                goto error;
+            }
+        } else if (vendor) {
+            if (vendor != vnd) {
+                virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                               _("CPU vendors do not match"));
+                goto error;
+            }
+        } else {
+            vendor = vnd;
+        }
     }
 
-    base_model->data->ppc.pvr = model->data->ppc.pvr;
-    if (PowerPCDecode(cpu, base_model->data, models, nmodels, NULL) < 0)
-        goto error;
+    if (VIR_ALLOC(cpu) < 0 ||
+        !(cpu->model = strdup(model->name)))
+        goto no_memory;
 
-    if (!outputModel)
-        VIR_FREE(cpu->model);
+    if (vendor && !(cpu->vendor = strdup(vendor->name)))
+        goto no_memory;
+
+    cpu->type = VIR_CPU_TYPE_GUEST;
+    cpu->match = VIR_CPU_MATCH_EXACT;
 
 cleanup:
-    ppcModelFree(base_model);
     ppcMapFree(map);
 
     return cpu;
+
 no_memory:
     virReportOOMError();
 error:
-    ppcModelFree(model);
     virCPUDefFree(cpu);
     cpu = NULL;
     goto cleanup;
@@ -617,7 +609,7 @@ struct cpuArchDriver cpuDriverPowerPC = {
     .nodeData   = NULL,
 #endif
     .guestData  = NULL,
-    .baseline   = PowerPCBaseline,
+    .baseline   = ppcBaseline,
     .update     = PowerPCUpdate,
     .hasFeature = NULL,
 };
-- 
1.8.0.2




More information about the libvir-list mailing list