|
|
c480ed |
From 728231dcbbf2a4ab8a4bfe03fdf43d78bdeccbb0 Mon Sep 17 00:00:00 2001
|
|
|
c480ed |
Message-Id: <728231dcbbf2a4ab8a4bfe03fdf43d78bdeccbb0@dist-git>
|
|
|
c480ed |
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
|
|
c480ed |
Date: Fri, 21 Jun 2019 09:24:46 +0200
|
|
|
c480ed |
Subject: [PATCH] cpu: push more parsing logic into common code
|
|
|
c480ed |
MIME-Version: 1.0
|
|
|
c480ed |
Content-Type: text/plain; charset=UTF-8
|
|
|
c480ed |
Content-Transfer-Encoding: 8bit
|
|
|
c480ed |
|
|
|
c480ed |
The x86 and ppc impls both duplicate some logic when parsing CPU
|
|
|
c480ed |
features. Change the callback signature so that this duplication can be
|
|
|
c480ed |
pushed up a level to common code.
|
|
|
c480ed |
|
|
|
c480ed |
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c480ed |
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
|
c480ed |
(cherry picked from commit 0815f519784a7c565c543498777dc25f129620f9)
|
|
|
c480ed |
|
|
|
c480ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1686895
|
|
|
c480ed |
|
|
|
c480ed |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c480ed |
Message-Id: <c770b678131dc5e207cbe84d276a2774e0c807c7.1561068591.git.jdenemar@redhat.com>
|
|
|
c480ed |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
c480ed |
---
|
|
|
c480ed |
src/cpu/cpu_map.c | 98 +++++++++++++---------
|
|
|
c480ed |
src/cpu/cpu_map.h | 22 ++---
|
|
|
c480ed |
src/cpu/cpu_ppc64.c | 112 ++++++-------------------
|
|
|
c480ed |
src/cpu/cpu_x86.c | 196 +++++++++++++-------------------------------
|
|
|
c480ed |
4 files changed, 143 insertions(+), 285 deletions(-)
|
|
|
c480ed |
|
|
|
c480ed |
diff --git a/src/cpu/cpu_map.c b/src/cpu/cpu_map.c
|
|
|
c480ed |
index 333c7ef24f..ac7e58037a 100644
|
|
|
c480ed |
--- a/src/cpu/cpu_map.c
|
|
|
c480ed |
+++ b/src/cpu/cpu_map.c
|
|
|
c480ed |
@@ -35,31 +35,47 @@
|
|
|
c480ed |
|
|
|
c480ed |
VIR_LOG_INIT("cpu.cpu_map");
|
|
|
c480ed |
|
|
|
c480ed |
-VIR_ENUM_IMPL(cpuMapElement, CPU_MAP_ELEMENT_LAST,
|
|
|
c480ed |
- "vendor",
|
|
|
c480ed |
- "feature",
|
|
|
c480ed |
- "model")
|
|
|
c480ed |
-
|
|
|
c480ed |
-
|
|
|
c480ed |
-static int load(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- cpuMapElement element,
|
|
|
c480ed |
- cpuMapLoadCallback callback,
|
|
|
c480ed |
- void *data)
|
|
|
c480ed |
+static int
|
|
|
c480ed |
+loadData(const char *mapfile,
|
|
|
c480ed |
+ xmlXPathContextPtr ctxt,
|
|
|
c480ed |
+ const char *element,
|
|
|
c480ed |
+ cpuMapLoadCallback callback,
|
|
|
c480ed |
+ void *data)
|
|
|
c480ed |
{
|
|
|
c480ed |
int ret = -1;
|
|
|
c480ed |
xmlNodePtr ctxt_node;
|
|
|
c480ed |
xmlNodePtr *nodes = NULL;
|
|
|
c480ed |
int n;
|
|
|
c480ed |
+ size_t i;
|
|
|
c480ed |
+ int rv;
|
|
|
c480ed |
|
|
|
c480ed |
ctxt_node = ctxt->node;
|
|
|
c480ed |
|
|
|
c480ed |
- n = virXPathNodeSet(cpuMapElementTypeToString(element), ctxt, &nodes);
|
|
|
c480ed |
- if (n < 0)
|
|
|
c480ed |
+ if ((n = virXPathNodeSet(element, ctxt, &nodes)) < 0)
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
|
|
|
c480ed |
- if (n > 0 &&
|
|
|
c480ed |
- callback(element, ctxt, nodes, n, data) < 0)
|
|
|
c480ed |
+ if (n > 0 && !callback) {
|
|
|
c480ed |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
+ _("Unexpected element '%s' in CPU map '%s'"), element, mapfile);
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+
|
|
|
c480ed |
+ for (i = 0; i < n; i++) {
|
|
|
c480ed |
+ xmlNodePtr old = ctxt->node;
|
|
|
c480ed |
+ char *name = virXMLPropString(nodes[i], "name");
|
|
|
c480ed |
+ if (!name) {
|
|
|
c480ed |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
+ _("cannot find %s name in CPU map '%s'"), element, mapfile);
|
|
|
c480ed |
+ goto cleanup;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+ VIR_DEBUG("Load %s name %s", element, name);
|
|
|
c480ed |
+ ctxt->node = nodes[i];
|
|
|
c480ed |
+ rv = callback(ctxt, name, data);
|
|
|
c480ed |
+ ctxt->node = old;
|
|
|
c480ed |
+ VIR_FREE(name);
|
|
|
c480ed |
+ if (rv < 0)
|
|
|
c480ed |
+ goto cleanup;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
|
|
|
c480ed |
ret = 0;
|
|
|
c480ed |
|
|
|
c480ed |
@@ -72,13 +88,14 @@ static int load(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
|
|
|
c480ed |
static int
|
|
|
c480ed |
cpuMapLoadInclude(const char *filename,
|
|
|
c480ed |
- cpuMapLoadCallback cb,
|
|
|
c480ed |
+ cpuMapLoadCallback vendorCB,
|
|
|
c480ed |
+ cpuMapLoadCallback featureCB,
|
|
|
c480ed |
+ cpuMapLoadCallback modelCB,
|
|
|
c480ed |
void *data)
|
|
|
c480ed |
{
|
|
|
c480ed |
xmlDocPtr xml = NULL;
|
|
|
c480ed |
xmlXPathContextPtr ctxt = NULL;
|
|
|
c480ed |
int ret = -1;
|
|
|
c480ed |
- int element;
|
|
|
c480ed |
char *mapfile;
|
|
|
c480ed |
|
|
|
c480ed |
if (!(mapfile = virFileFindResource(filename,
|
|
|
c480ed |
@@ -93,13 +110,14 @@ cpuMapLoadInclude(const char *filename,
|
|
|
c480ed |
|
|
|
c480ed |
ctxt->node = xmlDocGetRootElement(xml);
|
|
|
c480ed |
|
|
|
c480ed |
- for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) {
|
|
|
c480ed |
- if (load(ctxt, element, cb, data) < 0) {
|
|
|
c480ed |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
- _("cannot parse CPU map '%s'"), mapfile);
|
|
|
c480ed |
- goto cleanup;
|
|
|
c480ed |
- }
|
|
|
c480ed |
- }
|
|
|
c480ed |
+ if (loadData(mapfile, ctxt, "vendor", vendorCB, data) < 0)
|
|
|
c480ed |
+ goto cleanup;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (loadData(mapfile, ctxt, "feature", featureCB, data) < 0)
|
|
|
c480ed |
+ goto cleanup;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (loadData(mapfile, ctxt, "model", modelCB, data) < 0)
|
|
|
c480ed |
+ goto cleanup;
|
|
|
c480ed |
|
|
|
c480ed |
ret = 0;
|
|
|
c480ed |
|
|
|
c480ed |
@@ -114,7 +132,9 @@ cpuMapLoadInclude(const char *filename,
|
|
|
c480ed |
|
|
|
c480ed |
static int
|
|
|
c480ed |
loadIncludes(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- cpuMapLoadCallback callback,
|
|
|
c480ed |
+ cpuMapLoadCallback vendorCB,
|
|
|
c480ed |
+ cpuMapLoadCallback featureCB,
|
|
|
c480ed |
+ cpuMapLoadCallback modelCB,
|
|
|
c480ed |
void *data)
|
|
|
c480ed |
{
|
|
|
c480ed |
int ret = -1;
|
|
|
c480ed |
@@ -137,7 +157,7 @@ loadIncludes(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
}
|
|
|
c480ed |
VIR_DEBUG("Finding CPU map include '%s'", filename);
|
|
|
c480ed |
- if (cpuMapLoadInclude(filename, callback, data) < 0) {
|
|
|
c480ed |
+ if (cpuMapLoadInclude(filename, vendorCB, featureCB, modelCB, data) < 0) {
|
|
|
c480ed |
VIR_FREE(filename);
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
}
|
|
|
c480ed |
@@ -155,7 +175,9 @@ loadIncludes(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
int cpuMapLoad(const char *arch,
|
|
|
c480ed |
- cpuMapLoadCallback cb,
|
|
|
c480ed |
+ cpuMapLoadCallback vendorCB,
|
|
|
c480ed |
+ cpuMapLoadCallback featureCB,
|
|
|
c480ed |
+ cpuMapLoadCallback modelCB,
|
|
|
c480ed |
void *data)
|
|
|
c480ed |
{
|
|
|
c480ed |
xmlDocPtr xml = NULL;
|
|
|
c480ed |
@@ -163,7 +185,6 @@ int cpuMapLoad(const char *arch,
|
|
|
c480ed |
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
c480ed |
char *xpath = NULL;
|
|
|
c480ed |
int ret = -1;
|
|
|
c480ed |
- int element;
|
|
|
c480ed |
char *mapfile;
|
|
|
c480ed |
|
|
|
c480ed |
if (!(mapfile = virFileFindResource("cpu_map.xml",
|
|
|
c480ed |
@@ -179,12 +200,6 @@ int cpuMapLoad(const char *arch,
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
- if (cb == NULL) {
|
|
|
c480ed |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
- "%s", _("no callback provided"));
|
|
|
c480ed |
- goto cleanup;
|
|
|
c480ed |
- }
|
|
|
c480ed |
-
|
|
|
c480ed |
if (!(xml = virXMLParseFileCtxt(mapfile, &ctxt)))
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
|
|
|
c480ed |
@@ -202,15 +217,16 @@ int cpuMapLoad(const char *arch,
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
- for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) {
|
|
|
c480ed |
- if (load(ctxt, element, cb, data) < 0) {
|
|
|
c480ed |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
- _("cannot parse CPU map '%s'"), mapfile);
|
|
|
c480ed |
- goto cleanup;
|
|
|
c480ed |
- }
|
|
|
c480ed |
- }
|
|
|
c480ed |
+ if (loadData(mapfile, ctxt, "vendor", vendorCB, data) < 0)
|
|
|
c480ed |
+ goto cleanup;
|
|
|
c480ed |
|
|
|
c480ed |
- if (loadIncludes(ctxt, cb, data) < 0)
|
|
|
c480ed |
+ if (loadData(mapfile, ctxt, "feature", featureCB, data) < 0)
|
|
|
c480ed |
+ goto cleanup;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (loadData(mapfile, ctxt, "model", modelCB, data) < 0)
|
|
|
c480ed |
+ goto cleanup;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (loadIncludes(ctxt, vendorCB, featureCB, modelCB, data) < 0)
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
|
|
|
c480ed |
ret = 0;
|
|
|
c480ed |
diff --git a/src/cpu/cpu_map.h b/src/cpu/cpu_map.h
|
|
|
c480ed |
index 0c7507e98f..4596987150 100644
|
|
|
c480ed |
--- a/src/cpu/cpu_map.h
|
|
|
c480ed |
+++ b/src/cpu/cpu_map.h
|
|
|
c480ed |
@@ -26,28 +26,16 @@
|
|
|
c480ed |
|
|
|
c480ed |
# include "virxml.h"
|
|
|
c480ed |
|
|
|
c480ed |
-
|
|
|
c480ed |
-typedef enum {
|
|
|
c480ed |
- CPU_MAP_ELEMENT_VENDOR,
|
|
|
c480ed |
- CPU_MAP_ELEMENT_FEATURE,
|
|
|
c480ed |
- CPU_MAP_ELEMENT_MODEL,
|
|
|
c480ed |
-
|
|
|
c480ed |
- CPU_MAP_ELEMENT_LAST
|
|
|
c480ed |
-} cpuMapElement;
|
|
|
c480ed |
-
|
|
|
c480ed |
-VIR_ENUM_DECL(cpuMapElement)
|
|
|
c480ed |
-
|
|
|
c480ed |
-
|
|
|
c480ed |
typedef int
|
|
|
c480ed |
-(*cpuMapLoadCallback) (cpuMapElement element,
|
|
|
c480ed |
- xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- xmlNodePtr *nodes,
|
|
|
c480ed |
- int n,
|
|
|
c480ed |
+(*cpuMapLoadCallback) (xmlXPathContextPtr ctxt,
|
|
|
c480ed |
+ const char *name,
|
|
|
c480ed |
void *data);
|
|
|
c480ed |
|
|
|
c480ed |
int
|
|
|
c480ed |
cpuMapLoad(const char *arch,
|
|
|
c480ed |
- cpuMapLoadCallback cb,
|
|
|
c480ed |
+ cpuMapLoadCallback vendorCB,
|
|
|
c480ed |
+ cpuMapLoadCallback featureCB,
|
|
|
c480ed |
+ cpuMapLoadCallback modelCB,
|
|
|
c480ed |
void *data);
|
|
|
c480ed |
|
|
|
c480ed |
#endif /* __VIR_CPU_MAP_H__ */
|
|
|
c480ed |
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
|
|
|
c480ed |
index d562677fa3..75da5b77d8 100644
|
|
|
c480ed |
--- a/src/cpu/cpu_ppc64.c
|
|
|
c480ed |
+++ b/src/cpu/cpu_ppc64.c
|
|
|
c480ed |
@@ -281,21 +281,19 @@ ppc64MapFree(struct ppc64_map *map)
|
|
|
c480ed |
VIR_FREE(map);
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
-static struct ppc64_vendor *
|
|
|
c480ed |
-ppc64VendorParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- struct ppc64_map *map)
|
|
|
c480ed |
+static int
|
|
|
c480ed |
+ppc64VendorParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
|
|
c480ed |
+ const char *name,
|
|
|
c480ed |
+ void *data)
|
|
|
c480ed |
{
|
|
|
c480ed |
+ struct ppc64_map *map = data;
|
|
|
c480ed |
struct ppc64_vendor *vendor;
|
|
|
c480ed |
|
|
|
c480ed |
if (VIR_ALLOC(vendor) < 0)
|
|
|
c480ed |
- return NULL;
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
|
|
|
c480ed |
- vendor->name = virXPathString("string(@name)", ctxt);
|
|
|
c480ed |
- if (!vendor->name) {
|
|
|
c480ed |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
- "%s", _("Missing CPU vendor name"));
|
|
|
c480ed |
+ if (VIR_STRDUP(vendor->name, name) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
- }
|
|
|
c480ed |
|
|
|
c480ed |
if (ppc64VendorFind(map, vendor->name)) {
|
|
|
c480ed |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
@@ -303,57 +301,36 @@ ppc64VendorParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
- return vendor;
|
|
|
c480ed |
+ if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0)
|
|
|
c480ed |
+ goto error;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ return 0;
|
|
|
c480ed |
|
|
|
c480ed |
error:
|
|
|
c480ed |
ppc64VendorFree(vendor);
|
|
|
c480ed |
- return NULL;
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
static int
|
|
|
c480ed |
-ppc64VendorsLoad(struct ppc64_map *map,
|
|
|
c480ed |
- xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- xmlNodePtr *nodes,
|
|
|
c480ed |
- int n)
|
|
|
c480ed |
-{
|
|
|
c480ed |
- struct ppc64_vendor *vendor;
|
|
|
c480ed |
- size_t i;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (VIR_ALLOC_N(map->vendors, n) < 0)
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- for (i = 0; i < n; i++) {
|
|
|
c480ed |
- ctxt->node = nodes[i];
|
|
|
c480ed |
- if (!(vendor = ppc64VendorParse(ctxt, map)))
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
- map->vendors[map->nvendors++] = vendor;
|
|
|
c480ed |
- }
|
|
|
c480ed |
-
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-}
|
|
|
c480ed |
-
|
|
|
c480ed |
-
|
|
|
c480ed |
-static struct ppc64_model *
|
|
|
c480ed |
ppc64ModelParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- struct ppc64_map *map)
|
|
|
c480ed |
+ const char *name,
|
|
|
c480ed |
+ void *data)
|
|
|
c480ed |
{
|
|
|
c480ed |
+ struct ppc64_map *map = data;
|
|
|
c480ed |
struct ppc64_model *model;
|
|
|
c480ed |
xmlNodePtr *nodes = NULL;
|
|
|
c480ed |
char *vendor = NULL;
|
|
|
c480ed |
unsigned long pvr;
|
|
|
c480ed |
size_t i;
|
|
|
c480ed |
int n;
|
|
|
c480ed |
+ int ret = -1;
|
|
|
c480ed |
|
|
|
c480ed |
if (VIR_ALLOC(model) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
|
|
|
c480ed |
- model->name = virXPathString("string(@name)", ctxt);
|
|
|
c480ed |
- if (!model->name) {
|
|
|
c480ed |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
- "%s", _("Missing CPU model name"));
|
|
|
c480ed |
+ if (VIR_STRDUP(model->name, name) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
- }
|
|
|
c480ed |
|
|
|
c480ed |
if (ppc64ModelFind(map, model->name)) {
|
|
|
c480ed |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
@@ -410,63 +387,22 @@ ppc64ModelParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
model->data.pvr[i].mask = pvr;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
+ if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0)
|
|
|
c480ed |
+ goto error;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ ret = 0;
|
|
|
c480ed |
+
|
|
|
c480ed |
cleanup:
|
|
|
c480ed |
VIR_FREE(vendor);
|
|
|
c480ed |
VIR_FREE(nodes);
|
|
|
c480ed |
- return model;
|
|
|
c480ed |
+ return ret;
|
|
|
c480ed |
|
|
|
c480ed |
error:
|
|
|
c480ed |
ppc64ModelFree(model);
|
|
|
c480ed |
- model = NULL;
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
-static int
|
|
|
c480ed |
-ppc64ModelsLoad(struct ppc64_map *map,
|
|
|
c480ed |
- xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- xmlNodePtr *nodes,
|
|
|
c480ed |
- int n)
|
|
|
c480ed |
-{
|
|
|
c480ed |
- struct ppc64_model *model;
|
|
|
c480ed |
- size_t i;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (VIR_ALLOC_N(map->models, n) < 0)
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- for (i = 0; i < n; i++) {
|
|
|
c480ed |
- ctxt->node = nodes[i];
|
|
|
c480ed |
- if (!(model = ppc64ModelParse(ctxt, map)))
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
- map->models[map->nmodels++] = model;
|
|
|
c480ed |
- }
|
|
|
c480ed |
-
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-}
|
|
|
c480ed |
-
|
|
|
c480ed |
-
|
|
|
c480ed |
-static int
|
|
|
c480ed |
-ppc64MapLoadCallback(cpuMapElement element,
|
|
|
c480ed |
- xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- xmlNodePtr *nodes,
|
|
|
c480ed |
- int n,
|
|
|
c480ed |
- void *data)
|
|
|
c480ed |
-{
|
|
|
c480ed |
- struct ppc64_map *map = data;
|
|
|
c480ed |
-
|
|
|
c480ed |
- switch (element) {
|
|
|
c480ed |
- case CPU_MAP_ELEMENT_VENDOR:
|
|
|
c480ed |
- return ppc64VendorsLoad(map, ctxt, nodes, n);
|
|
|
c480ed |
- case CPU_MAP_ELEMENT_MODEL:
|
|
|
c480ed |
- return ppc64ModelsLoad(map, ctxt, nodes, n);
|
|
|
c480ed |
- case CPU_MAP_ELEMENT_FEATURE:
|
|
|
c480ed |
- case CPU_MAP_ELEMENT_LAST:
|
|
|
c480ed |
- break;
|
|
|
c480ed |
- }
|
|
|
c480ed |
-
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-}
|
|
|
c480ed |
-
|
|
|
c480ed |
static struct ppc64_map *
|
|
|
c480ed |
ppc64LoadMap(void)
|
|
|
c480ed |
{
|
|
|
c480ed |
@@ -475,7 +411,7 @@ ppc64LoadMap(void)
|
|
|
c480ed |
if (VIR_ALLOC(map) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
|
|
|
c480ed |
- if (cpuMapLoad("ppc64", ppc64MapLoadCallback, map) < 0)
|
|
|
c480ed |
+ if (cpuMapLoad("ppc64", ppc64VendorParse, NULL, ppc64ModelParse, map) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
|
|
|
c480ed |
return map;
|
|
|
c480ed |
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
|
|
|
c480ed |
index 124aa5fd5e..11dbd1e757 100644
|
|
|
c480ed |
--- a/src/cpu/cpu_x86.c
|
|
|
c480ed |
+++ b/src/cpu/cpu_x86.c
|
|
|
c480ed |
@@ -720,22 +720,21 @@ x86VendorFind(virCPUx86MapPtr map,
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
-static virCPUx86VendorPtr
|
|
|
c480ed |
+static int
|
|
|
c480ed |
x86VendorParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- virCPUx86MapPtr map)
|
|
|
c480ed |
+ const char *name,
|
|
|
c480ed |
+ void *data)
|
|
|
c480ed |
{
|
|
|
c480ed |
+ virCPUx86MapPtr map = data;
|
|
|
c480ed |
virCPUx86VendorPtr vendor = NULL;
|
|
|
c480ed |
char *string = NULL;
|
|
|
c480ed |
+ int ret = -1;
|
|
|
c480ed |
|
|
|
c480ed |
if (VIR_ALLOC(vendor) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
|
|
|
c480ed |
- vendor->name = virXPathString("string(@name)", ctxt);
|
|
|
c480ed |
- if (!vendor->name) {
|
|
|
c480ed |
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
c480ed |
- _("Missing CPU vendor name"));
|
|
|
c480ed |
+ if (VIR_STRDUP(vendor->name, name) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
- }
|
|
|
c480ed |
|
|
|
c480ed |
if (x86VendorFind(map, vendor->name)) {
|
|
|
c480ed |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
@@ -754,40 +753,21 @@ x86VendorParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
if (virCPUx86VendorToCPUID(string, &vendor->cpuid) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
|
|
|
c480ed |
+ if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0)
|
|
|
c480ed |
+ goto error;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ ret = 0;
|
|
|
c480ed |
+
|
|
|
c480ed |
cleanup:
|
|
|
c480ed |
VIR_FREE(string);
|
|
|
c480ed |
- return vendor;
|
|
|
c480ed |
+ return ret;
|
|
|
c480ed |
|
|
|
c480ed |
error:
|
|
|
c480ed |
x86VendorFree(vendor);
|
|
|
c480ed |
- vendor = NULL;
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
-static int
|
|
|
c480ed |
-x86VendorsLoad(virCPUx86MapPtr map,
|
|
|
c480ed |
- xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- xmlNodePtr *nodes,
|
|
|
c480ed |
- int n)
|
|
|
c480ed |
-{
|
|
|
c480ed |
- virCPUx86VendorPtr vendor;
|
|
|
c480ed |
- size_t i;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (VIR_ALLOC_N(map->vendors, n) < 0)
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- for (i = 0; i < n; i++) {
|
|
|
c480ed |
- ctxt->node = nodes[i];
|
|
|
c480ed |
- if (!(vendor = x86VendorParse(ctxt, map)))
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
- map->vendors[map->nvendors++] = vendor;
|
|
|
c480ed |
- }
|
|
|
c480ed |
-
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-}
|
|
|
c480ed |
-
|
|
|
c480ed |
-
|
|
|
c480ed |
static virCPUx86FeaturePtr
|
|
|
c480ed |
x86FeatureNew(void)
|
|
|
c480ed |
{
|
|
|
c480ed |
@@ -909,27 +889,27 @@ x86ParseCPUID(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
-static virCPUx86FeaturePtr
|
|
|
c480ed |
+static int
|
|
|
c480ed |
x86FeatureParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- virCPUx86MapPtr map)
|
|
|
c480ed |
+ const char *name,
|
|
|
c480ed |
+ void *data)
|
|
|
c480ed |
{
|
|
|
c480ed |
+ virCPUx86MapPtr map = data;
|
|
|
c480ed |
xmlNodePtr *nodes = NULL;
|
|
|
c480ed |
virCPUx86FeaturePtr feature;
|
|
|
c480ed |
virCPUx86CPUID cpuid;
|
|
|
c480ed |
size_t i;
|
|
|
c480ed |
int n;
|
|
|
c480ed |
char *str = NULL;
|
|
|
c480ed |
+ int ret = -1;
|
|
|
c480ed |
|
|
|
c480ed |
if (!(feature = x86FeatureNew()))
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
|
|
|
c480ed |
feature->migratable = true;
|
|
|
c480ed |
- feature->name = virXPathString("string(@name)", ctxt);
|
|
|
c480ed |
- if (!feature->name) {
|
|
|
c480ed |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
- "%s", _("Missing CPU feature name"));
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (VIR_STRDUP(feature->name, name) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
- }
|
|
|
c480ed |
|
|
|
c480ed |
if (x86FeatureFind(map, feature->name)) {
|
|
|
c480ed |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
@@ -957,46 +937,28 @@ x86FeatureParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
+ if (!feature->migratable &&
|
|
|
c480ed |
+ VIR_APPEND_ELEMENT_COPY(map->migrate_blockers,
|
|
|
c480ed |
+ map->nblockers,
|
|
|
c480ed |
+ feature) < 0)
|
|
|
c480ed |
+ goto error;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (VIR_APPEND_ELEMENT(map->features, map->nfeatures, feature) < 0)
|
|
|
c480ed |
+ goto error;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ ret = 0;
|
|
|
c480ed |
+
|
|
|
c480ed |
cleanup:
|
|
|
c480ed |
VIR_FREE(nodes);
|
|
|
c480ed |
VIR_FREE(str);
|
|
|
c480ed |
- return feature;
|
|
|
c480ed |
+ return ret;
|
|
|
c480ed |
|
|
|
c480ed |
error:
|
|
|
c480ed |
x86FeatureFree(feature);
|
|
|
c480ed |
- feature = NULL;
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
-static int
|
|
|
c480ed |
-x86FeaturesLoad(virCPUx86MapPtr map,
|
|
|
c480ed |
- xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- xmlNodePtr *nodes,
|
|
|
c480ed |
- int n)
|
|
|
c480ed |
-{
|
|
|
c480ed |
- virCPUx86FeaturePtr feature;
|
|
|
c480ed |
- size_t i;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (VIR_ALLOC_N(map->features, n) < 0)
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- for (i = 0; i < n; i++) {
|
|
|
c480ed |
- ctxt->node = nodes[i];
|
|
|
c480ed |
- if (!(feature = x86FeatureParse(ctxt, map)))
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
- map->features[map->nfeatures++] = feature;
|
|
|
c480ed |
- if (!feature->migratable &&
|
|
|
c480ed |
- VIR_APPEND_ELEMENT(map->migrate_blockers,
|
|
|
c480ed |
- map->nblockers,
|
|
|
c480ed |
- feature) < 0)
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
- }
|
|
|
c480ed |
-
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-}
|
|
|
c480ed |
-
|
|
|
c480ed |
-
|
|
|
c480ed |
static virCPUx86ModelPtr
|
|
|
c480ed |
x86ModelNew(void)
|
|
|
c480ed |
{
|
|
|
c480ed |
@@ -1192,47 +1154,46 @@ x86ModelCompare(virCPUx86ModelPtr model1,
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
-static virCPUx86ModelPtr
|
|
|
c480ed |
+static int
|
|
|
c480ed |
x86ModelParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- virCPUx86MapPtr map)
|
|
|
c480ed |
+ const char *name,
|
|
|
c480ed |
+ void *data)
|
|
|
c480ed |
{
|
|
|
c480ed |
+ virCPUx86MapPtr map = data;
|
|
|
c480ed |
xmlNodePtr *nodes = NULL;
|
|
|
c480ed |
virCPUx86ModelPtr model;
|
|
|
c480ed |
char *vendor = NULL;
|
|
|
c480ed |
size_t i;
|
|
|
c480ed |
int n;
|
|
|
c480ed |
+ int ret = -1;
|
|
|
c480ed |
|
|
|
c480ed |
if (!(model = x86ModelNew()))
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
|
|
|
c480ed |
- model->name = virXPathString("string(@name)", ctxt);
|
|
|
c480ed |
- if (!model->name) {
|
|
|
c480ed |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
- "%s", _("Missing CPU model name"));
|
|
|
c480ed |
+ if (VIR_STRDUP(model->name, name) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
- }
|
|
|
c480ed |
|
|
|
c480ed |
if (virXPathNode("./model", ctxt)) {
|
|
|
c480ed |
virCPUx86ModelPtr ancestor;
|
|
|
c480ed |
- char *name;
|
|
|
c480ed |
+ char *anname;
|
|
|
c480ed |
|
|
|
c480ed |
- name = virXPathString("string(./model/@name)", ctxt);
|
|
|
c480ed |
- if (!name) {
|
|
|
c480ed |
+ anname = virXPathString("string(./model/@name)", ctxt);
|
|
|
c480ed |
+ if (!anname) {
|
|
|
c480ed |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
_("Missing ancestor's name in CPU model %s"),
|
|
|
c480ed |
model->name);
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
- if (!(ancestor = x86ModelFind(map, name))) {
|
|
|
c480ed |
+ if (!(ancestor = x86ModelFind(map, anname))) {
|
|
|
c480ed |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
_("Ancestor model %s not found for CPU model %s"),
|
|
|
c480ed |
- name, model->name);
|
|
|
c480ed |
- VIR_FREE(name);
|
|
|
c480ed |
+ anname, model->name);
|
|
|
c480ed |
+ VIR_FREE(anname);
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
- VIR_FREE(name);
|
|
|
c480ed |
+ VIR_FREE(anname);
|
|
|
c480ed |
|
|
|
c480ed |
model->vendor = ancestor->vendor;
|
|
|
c480ed |
model->signature = ancestor->signature;
|
|
|
c480ed |
@@ -1287,62 +1248,43 @@ x86ModelParse(xmlXPathContextPtr ctxt,
|
|
|
c480ed |
|
|
|
c480ed |
for (i = 0; i < n; i++) {
|
|
|
c480ed |
virCPUx86FeaturePtr feature;
|
|
|
c480ed |
- char *name;
|
|
|
c480ed |
+ char *ftname;
|
|
|
c480ed |
|
|
|
c480ed |
- if (!(name = virXMLPropString(nodes[i], "name"))) {
|
|
|
c480ed |
+ if (!(ftname = virXMLPropString(nodes[i], "name"))) {
|
|
|
c480ed |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
_("Missing feature name for CPU model %s"), model->name);
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
- if (!(feature = x86FeatureFind(map, name))) {
|
|
|
c480ed |
+ if (!(feature = x86FeatureFind(map, ftname))) {
|
|
|
c480ed |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c480ed |
_("Feature %s required by CPU model %s not found"),
|
|
|
c480ed |
- name, model->name);
|
|
|
c480ed |
- VIR_FREE(name);
|
|
|
c480ed |
+ ftname, model->name);
|
|
|
c480ed |
+ VIR_FREE(ftname);
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
}
|
|
|
c480ed |
- VIR_FREE(name);
|
|
|
c480ed |
+ VIR_FREE(ftname);
|
|
|
c480ed |
|
|
|
c480ed |
if (x86DataAdd(&model->data, &feature->data))
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
+ if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0)
|
|
|
c480ed |
+ goto error;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ ret = 0;
|
|
|
c480ed |
+
|
|
|
c480ed |
cleanup:
|
|
|
c480ed |
VIR_FREE(vendor);
|
|
|
c480ed |
VIR_FREE(nodes);
|
|
|
c480ed |
- return model;
|
|
|
c480ed |
+ return ret;
|
|
|
c480ed |
|
|
|
c480ed |
error:
|
|
|
c480ed |
x86ModelFree(model);
|
|
|
c480ed |
- model = NULL;
|
|
|
c480ed |
goto cleanup;
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
-static int
|
|
|
c480ed |
-x86ModelsLoad(virCPUx86MapPtr map,
|
|
|
c480ed |
- xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- xmlNodePtr *nodes,
|
|
|
c480ed |
- int n)
|
|
|
c480ed |
-{
|
|
|
c480ed |
- virCPUx86ModelPtr model;
|
|
|
c480ed |
- size_t i;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (VIR_ALLOC_N(map->models, n) < 0)
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- for (i = 0; i < n; i++) {
|
|
|
c480ed |
- ctxt->node = nodes[i];
|
|
|
c480ed |
- if (!(model = x86ModelParse(ctxt, map)))
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
- map->models[map->nmodels++] = model;
|
|
|
c480ed |
- }
|
|
|
c480ed |
-
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-}
|
|
|
c480ed |
-
|
|
|
c480ed |
-
|
|
|
c480ed |
static void
|
|
|
c480ed |
x86MapFree(virCPUx86MapPtr map)
|
|
|
c480ed |
{
|
|
|
c480ed |
@@ -1372,30 +1314,6 @@ x86MapFree(virCPUx86MapPtr map)
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
-static int
|
|
|
c480ed |
-x86MapLoadCallback(cpuMapElement element,
|
|
|
c480ed |
- xmlXPathContextPtr ctxt,
|
|
|
c480ed |
- xmlNodePtr *nodes,
|
|
|
c480ed |
- int n,
|
|
|
c480ed |
- void *data)
|
|
|
c480ed |
-{
|
|
|
c480ed |
- virCPUx86MapPtr map = data;
|
|
|
c480ed |
-
|
|
|
c480ed |
- switch (element) {
|
|
|
c480ed |
- case CPU_MAP_ELEMENT_VENDOR:
|
|
|
c480ed |
- return x86VendorsLoad(map, ctxt, nodes, n);
|
|
|
c480ed |
- case CPU_MAP_ELEMENT_FEATURE:
|
|
|
c480ed |
- return x86FeaturesLoad(map, ctxt, nodes, n);
|
|
|
c480ed |
- case CPU_MAP_ELEMENT_MODEL:
|
|
|
c480ed |
- return x86ModelsLoad(map, ctxt, nodes, n);
|
|
|
c480ed |
- case CPU_MAP_ELEMENT_LAST:
|
|
|
c480ed |
- break;
|
|
|
c480ed |
- }
|
|
|
c480ed |
-
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-}
|
|
|
c480ed |
-
|
|
|
c480ed |
-
|
|
|
c480ed |
static virCPUx86MapPtr
|
|
|
c480ed |
virCPUx86LoadMap(void)
|
|
|
c480ed |
{
|
|
|
c480ed |
@@ -1404,7 +1322,7 @@ virCPUx86LoadMap(void)
|
|
|
c480ed |
if (VIR_ALLOC(map) < 0)
|
|
|
c480ed |
return NULL;
|
|
|
c480ed |
|
|
|
c480ed |
- if (cpuMapLoad("x86", x86MapLoadCallback, map) < 0)
|
|
|
c480ed |
+ if (cpuMapLoad("x86", x86VendorParse, x86FeatureParse, x86ModelParse, map) < 0)
|
|
|
c480ed |
goto error;
|
|
|
c480ed |
|
|
|
c480ed |
return map;
|
|
|
c480ed |
--
|
|
|
c480ed |
2.22.0
|
|
|
c480ed |
|