]> xenbits.xensource.com Git - libvirt.git/commitdiff
cpu-driver: Fix the cross driver function call
authorDaniel Hansel <daniel.hansel@linux.vnet.ibm.com>
Thu, 20 Nov 2014 10:08:21 +0000 (11:08 +0100)
committerEric Blake <eblake@redhat.com>
Tue, 2 Dec 2014 17:18:55 +0000 (10:18 -0700)
For Intel and PowerPC the implementation is calling a cpu driver
function across driver layers (i.e. from qemu driver directly to cpu
driver).
The correct behavior is to use libvirt API functionality to perform such
a inter-driver call.

This patch introduces a new cpu driver API function getModels() to
retrieve the cpu models. The currect implementation to process the
cpu_map XML content is transferred to the INTEL and PowerPC cpu driver
specific API functions.
Additionally processing the cpu_map XML file is not safe due to the fact
that the cpu map does not exist for all architectures. Therefore it is
better to encapsulate the processing in the architecture specific cpu
drivers.

Signed-off-by: Daniel Hansel <daniel.hansel@linux.vnet.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.vnet.ibm.com>
Reviewed-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
src/cpu/cpu.c
src/cpu/cpu.h
src/cpu/cpu_powerpc.c
src/cpu/cpu_x86.c

index 08bec5e56add00abc4edad96baf2ef94197cf1dc..788f68873d1718b41cdc9e8a49138e42a8094ba2 100644 (file)
@@ -724,43 +724,6 @@ cpuModelIsAllowed(const char *model,
     return false;
 }
 
-struct cpuGetModelsData
-{
-    char **data;
-    size_t len;  /* It includes the last element of DATA, which is NULL. */
-};
-
-static int
-cpuGetArchModelsCb(cpuMapElement element,
-                   xmlXPathContextPtr ctxt,
-                   void *cbdata)
-{
-    char *name;
-    struct cpuGetModelsData *data = cbdata;
-    if (element != CPU_MAP_ELEMENT_MODEL)
-        return 0;
-
-    name = virXPathString("string(@name)", ctxt);
-    if (name == NULL)
-        return -1;
-
-    if (!data->data) {
-        VIR_FREE(name);
-        data->len++;
-        return 0;
-    }
-
-    return VIR_INSERT_ELEMENT(data->data, data->len - 1, data->len, name);
-}
-
-
-static int
-cpuGetArchModels(const char *arch, struct cpuGetModelsData *data)
-{
-    return cpuMapLoad(arch, cpuGetArchModelsCb, data);
-}
-
-
 /**
  * cpuGetModels:
  *
@@ -774,18 +737,17 @@ cpuGetArchModels(const char *arch, struct cpuGetModelsData *data)
 int
 cpuGetModels(const char *archName, char ***models)
 {
-    struct cpuGetModelsData data;
-    virArch arch;
     struct cpuArchDriver *driver;
-    data.data = NULL;
-    data.len = 1;
+    virArch arch;
+
+    VIR_DEBUG("arch=%s", archName);
 
     arch = virArchFromString(archName);
     if (arch == VIR_ARCH_NONE) {
         virReportError(VIR_ERR_INVALID_ARG,
                        _("cannot find architecture %s"),
                        archName);
-        goto error;
+        return -1;
     }
 
     driver = cpuGetSubDriver(arch);
@@ -793,21 +755,15 @@ cpuGetModels(const char *archName, char ***models)
         virReportError(VIR_ERR_INVALID_ARG,
                        _("cannot find a driver for the architecture %s"),
                        archName);
-        goto error;
+        return -1;
     }
 
-    if (models && VIR_ALLOC_N(data.data, data.len) < 0)
-        goto error;
-
-    if (cpuGetArchModels(driver->name, &data) < 0)
-        goto error;
-
-    if (models)
-        *models = data.data;
-
-    return data.len - 1;
+    if (!driver->getModels) {
+        virReportError(VIR_ERR_NO_SUPPORT,
+                       _("CPU driver for %s has no CPU model support"),
+                       virArchToString(arch));
+        return -1;
+    }
 
- error:
-    virStringFreeList(data.data);
-    return -1;
+    return driver->getModels(models);
 }
index 339964ce3ae4102996ec01cafb8c8f16cbf667a2..09e953829f30473c4afefd514f4e6c311178a876 100644 (file)
@@ -100,6 +100,9 @@ typedef char *
 typedef virCPUDataPtr
 (*cpuArchDataParse) (const char *xmlStr);
 
+typedef int
+(*cpuArchGetModels) (char ***models);
+
 struct cpuArchDriver {
     const char *name;
     const virArch *arch;
@@ -115,6 +118,7 @@ struct cpuArchDriver {
     cpuArchHasFeature    hasFeature;
     cpuArchDataFormat   dataFormat;
     cpuArchDataParse    dataParse;
+    cpuArchGetModels    getModels;
 };
 
 
index 531868caefe4e722171a1b3ac695ad1d7a6b513b..871401b0170aeca0ab844d8ce5057d83404c5743 100644 (file)
@@ -650,6 +650,42 @@ ppcBaseline(virCPUDefPtr *cpus,
     goto cleanup;
 }
 
+static int
+ppcGetModels(char ***models)
+{
+    struct ppc_map *map;
+    struct ppc_model *model;
+    char *name;
+    size_t nmodels = 0;
+
+    if (!(map = ppcLoadMap()))
+        goto error;
+
+    if (models && VIR_ALLOC_N(*models, 0) < 0)
+        goto error;
+
+    model = map->models;
+    while (model != NULL) {
+        if (VIR_STRDUP(name, model->name) < 0)
+            goto error;
+
+        if (VIR_INSERT_ELEMENT(*models, 0, nmodels, name) < 0)
+            goto error;
+
+        model = model->next;
+    }
+
+ cleanup:
+    ppcMapFree(map);
+
+    return nmodels;
+
+ error:
+    virStringFreeList(*models);
+    nmodels = -1;
+    goto cleanup;
+}
+
 struct cpuArchDriver cpuDriverPowerPC = {
     .name = "ppc64",
     .arch = archs,
@@ -663,4 +699,5 @@ struct cpuArchDriver cpuDriverPowerPC = {
     .baseline   = ppcBaseline,
     .update     = ppcUpdate,
     .hasFeature = NULL,
+    .getModels  = ppcGetModels,
 };
index 026b54e0d46a79b127d727aa246c1d50c6036ff5..f6dcba41d087178b4fea0f8948aaa3e6b8069f45 100644 (file)
@@ -2160,6 +2160,38 @@ x86HasFeature(const virCPUData *data,
     return ret;
 }
 
+static int
+x86GetModels(char ***models)
+{
+    const struct x86_map *map;
+    struct x86_model *model;
+    char *name;
+    size_t nmodels = 0;
+
+    if (!(map = virCPUx86GetMap()))
+        return -1;
+
+    if (models && VIR_ALLOC_N(*models, 0) < 0)
+        goto error;
+
+    model = map->models;
+    while (model != NULL) {
+        if (VIR_STRDUP(name, model->name) < 0)
+            goto error;
+
+        if (VIR_INSERT_ELEMENT(*models, 0, nmodels, name) < 0)
+            goto error;
+
+        model = model->next;
+    }
+
+    return nmodels;
+
+ error:
+    virStringFreeList(*models);
+    return -1;
+}
+
 
 struct cpuArchDriver cpuDriverX86 = {
     .name = "x86",
@@ -2180,4 +2212,5 @@ struct cpuArchDriver cpuDriverX86 = {
     .hasFeature = x86HasFeature,
     .dataFormat = x86CPUDataFormat,
     .dataParse  = x86CPUDataParse,
+    .getModels  = x86GetModels,
 };