提交 4b7c45ef 编写于 作者: J Jiri Denemark

cpu: Rework CPU map loading

The architecture specific loaders are now called with a list of all
elements of a given type (rather than a single element at a time). This
avoids the need to reallocate the arrays in CPU maps for each element.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 82aca171
...@@ -48,27 +48,24 @@ static int load(xmlXPathContextPtr ctxt, ...@@ -48,27 +48,24 @@ static int load(xmlXPathContextPtr ctxt,
{ {
int ret = -1; int ret = -1;
xmlNodePtr ctxt_node; xmlNodePtr ctxt_node;
xmlNodePtr cur; xmlNodePtr *nodes = NULL;
int n;
ctxt_node = ctxt->node; ctxt_node = ctxt->node;
cur = ctxt_node->children; n = virXPathNodeSet(cpuMapElementTypeToString(element), ctxt, &nodes);
while (cur != NULL) { if (n < 0)
if (cur->type == XML_ELEMENT_NODE && goto cleanup;
xmlStrEqual(cur->name,
BAD_CAST cpuMapElementTypeToString(element))) {
ctxt->node = cur;
if (callback(element, ctxt, data) < 0)
goto cleanup;
}
cur = cur->next; if (n > 0 &&
} callback(element, ctxt, nodes, n, data) < 0)
goto cleanup;
ret = 0; ret = 0;
cleanup: cleanup:
ctxt->node = ctxt_node; ctxt->node = ctxt_node;
VIR_FREE(nodes);
return ret; return ret;
} }
......
...@@ -41,6 +41,8 @@ VIR_ENUM_DECL(cpuMapElement) ...@@ -41,6 +41,8 @@ VIR_ENUM_DECL(cpuMapElement)
typedef int typedef int
(*cpuMapLoadCallback) (cpuMapElement element, (*cpuMapLoadCallback) (cpuMapElement element,
xmlXPathContextPtr ctxt, xmlXPathContextPtr ctxt,
xmlNodePtr *nodes,
int n,
void *data); void *data);
int int
......
...@@ -292,74 +292,87 @@ ppc64MapFree(struct ppc64_map *map) ...@@ -292,74 +292,87 @@ ppc64MapFree(struct ppc64_map *map)
VIR_FREE(map); VIR_FREE(map);
} }
static int static struct ppc64_vendor *
ppc64VendorLoad(xmlXPathContextPtr ctxt, ppc64VendorParse(xmlXPathContextPtr ctxt,
struct ppc64_map *map) struct ppc64_map *map)
{ {
struct ppc64_vendor *vendor; struct ppc64_vendor *vendor;
if (VIR_ALLOC(vendor) < 0) if (VIR_ALLOC(vendor) < 0)
return -1; return NULL;
vendor->name = virXPathString("string(@name)", ctxt); vendor->name = virXPathString("string(@name)", ctxt);
if (!vendor->name) { if (!vendor->name) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Missing CPU vendor name")); "%s", _("Missing CPU vendor name"));
goto ignore; goto error;
} }
if (ppc64VendorFind(map, vendor->name)) { if (ppc64VendorFind(map, vendor->name)) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("CPU vendor %s already defined"), vendor->name); _("CPU vendor %s already defined"), vendor->name);
goto ignore; goto error;
} }
if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) return vendor;
goto ignore;
cleanup:
return 0;
ignore: error:
ppc64VendorFree(vendor); ppc64VendorFree(vendor);
goto cleanup; return NULL;
} }
static int static int
ppc64ModelLoad(xmlXPathContextPtr ctxt, ppc64VendorsLoad(struct ppc64_map *map,
struct ppc64_map *map) xmlXPathContextPtr ctxt,
xmlNodePtr *nodes,
int n)
{
struct ppc64_vendor *vendor;
size_t i;
if (VIR_ALLOC_N(map->vendors, n) < 0)
return -1;
for (i = 0; i < n; i++) {
ctxt->node = nodes[i];
if (!(vendor = ppc64VendorParse(ctxt, map)))
return -1;
map->vendors[map->nvendors++] = vendor;
}
return 0;
}
static struct ppc64_model *
ppc64ModelParse(xmlXPathContextPtr ctxt,
struct ppc64_map *map)
{ {
struct ppc64_model *model; struct ppc64_model *model;
xmlNodePtr *nodes = NULL; xmlNodePtr *nodes = NULL;
xmlNodePtr bookmark;
char *vendor = NULL; char *vendor = NULL;
unsigned long pvr; unsigned long pvr;
size_t i; size_t i;
int n; int n;
/* Save the node the context was pointing to, as we're going
* to change it later. It's going to be restored on exit */
bookmark = ctxt->node;
if (VIR_ALLOC(model) < 0) if (VIR_ALLOC(model) < 0)
return -1; goto error;
if (VIR_ALLOC(model->data) < 0) { if (VIR_ALLOC(model->data) < 0)
ppc64ModelFree(model); goto error;
return -1;
}
model->name = virXPathString("string(@name)", ctxt); model->name = virXPathString("string(@name)", ctxt);
if (!model->name) { if (!model->name) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Missing CPU model name")); "%s", _("Missing CPU model name"));
goto ignore; goto error;
} }
if (ppc64ModelFind(map, model->name)) { if (ppc64ModelFind(map, model->name)) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("CPU model %s already defined"), model->name); _("CPU model %s already defined"), model->name);
goto ignore; goto error;
} }
if (virXPathBoolean("boolean(./vendor)", ctxt)) { if (virXPathBoolean("boolean(./vendor)", ctxt)) {
...@@ -368,14 +381,14 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, ...@@ -368,14 +381,14 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid vendor element in CPU model %s"), _("Invalid vendor element in CPU model %s"),
model->name); model->name);
goto ignore; goto error;
} }
if (!(model->vendor = ppc64VendorFind(map, vendor))) { if (!(model->vendor = ppc64VendorFind(map, vendor))) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown vendor %s referenced by CPU model %s"), _("Unknown vendor %s referenced by CPU model %s"),
vendor, model->name); vendor, model->name);
goto ignore; goto error;
} }
} }
...@@ -383,11 +396,11 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, ...@@ -383,11 +396,11 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing PVR information for CPU model %s"), _("Missing PVR information for CPU model %s"),
model->name); model->name);
goto ignore; goto error;
} }
if (VIR_ALLOC_N(model->data->pvr, n) < 0) if (VIR_ALLOC_N(model->data->pvr, n) < 0)
goto ignore; goto error;
model->data->len = n; model->data->len = n;
...@@ -398,7 +411,7 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, ...@@ -398,7 +411,7 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing or invalid PVR value in CPU model %s"), _("Missing or invalid PVR value in CPU model %s"),
model->name); model->name);
goto ignore; goto error;
} }
model->data->pvr[i].value = pvr; model->data->pvr[i].value = pvr;
...@@ -406,37 +419,60 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, ...@@ -406,37 +419,60 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing or invalid PVR mask in CPU model %s"), _("Missing or invalid PVR mask in CPU model %s"),
model->name); model->name);
goto ignore; goto error;
} }
model->data->pvr[i].mask = pvr; model->data->pvr[i].mask = pvr;
} }
if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0)
goto ignore;
cleanup: cleanup:
ctxt->node = bookmark;
VIR_FREE(vendor); VIR_FREE(vendor);
VIR_FREE(nodes); VIR_FREE(nodes);
return 0; return model;
ignore: error:
ppc64ModelFree(model); ppc64ModelFree(model);
model = NULL;
goto cleanup; goto cleanup;
} }
static int
ppc64ModelsLoad(struct ppc64_map *map,
xmlXPathContextPtr ctxt,
xmlNodePtr *nodes,
int n)
{
struct ppc64_model *model;
size_t i;
if (VIR_ALLOC_N(map->models, n) < 0)
return -1;
for (i = 0; i < n; i++) {
ctxt->node = nodes[i];
if (!(model = ppc64ModelParse(ctxt, map)))
return -1;
map->models[map->nmodels++] = model;
}
return 0;
}
static int static int
ppc64MapLoadCallback(cpuMapElement element, ppc64MapLoadCallback(cpuMapElement element,
xmlXPathContextPtr ctxt, xmlXPathContextPtr ctxt,
xmlNodePtr *nodes,
int n,
void *data) void *data)
{ {
struct ppc64_map *map = data; struct ppc64_map *map = data;
switch (element) { switch (element) {
case CPU_MAP_ELEMENT_VENDOR: case CPU_MAP_ELEMENT_VENDOR:
return ppc64VendorLoad(ctxt, map); return ppc64VendorsLoad(map, ctxt, nodes, n);
case CPU_MAP_ELEMENT_MODEL: case CPU_MAP_ELEMENT_MODEL:
return ppc64ModelLoad(ctxt, map); return ppc64ModelsLoad(map, ctxt, nodes, n);
case CPU_MAP_ELEMENT_FEATURE: case CPU_MAP_ELEMENT_FEATURE:
case CPU_MAP_ELEMENT_LAST: case CPU_MAP_ELEMENT_LAST:
break; break;
......
...@@ -56,6 +56,7 @@ typedef virCPUx86Feature *virCPUx86FeaturePtr; ...@@ -56,6 +56,7 @@ typedef virCPUx86Feature *virCPUx86FeaturePtr;
struct _virCPUx86Feature { struct _virCPUx86Feature {
char *name; char *name;
virCPUx86Data *data; virCPUx86Data *data;
bool migratable;
}; };
typedef struct _virCPUx86KVMFeature virCPUx86KVMFeature; typedef struct _virCPUx86KVMFeature virCPUx86KVMFeature;
...@@ -516,28 +517,27 @@ x86VendorFind(virCPUx86MapPtr map, ...@@ -516,28 +517,27 @@ x86VendorFind(virCPUx86MapPtr map,
} }
static int static virCPUx86VendorPtr
x86VendorLoad(xmlXPathContextPtr ctxt, x86VendorParse(xmlXPathContextPtr ctxt,
virCPUx86MapPtr map) virCPUx86MapPtr map)
{ {
virCPUx86VendorPtr vendor = NULL; virCPUx86VendorPtr vendor = NULL;
char *string = NULL; char *string = NULL;
int ret = -1;
if (VIR_ALLOC(vendor) < 0) if (VIR_ALLOC(vendor) < 0)
goto cleanup; goto error;
vendor->name = virXPathString("string(@name)", ctxt); vendor->name = virXPathString("string(@name)", ctxt);
if (!vendor->name) { if (!vendor->name) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing CPU vendor name")); _("Missing CPU vendor name"));
goto cleanup; goto error;
} }
if (x86VendorFind(map, vendor->name)) { if (x86VendorFind(map, vendor->name)) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("CPU vendor %s already defined"), vendor->name); _("CPU vendor %s already defined"), vendor->name);
goto cleanup; goto error;
} }
string = virXPathString("string(@string)", ctxt); string = virXPathString("string(@string)", ctxt);
...@@ -545,12 +545,12 @@ x86VendorLoad(xmlXPathContextPtr ctxt, ...@@ -545,12 +545,12 @@ x86VendorLoad(xmlXPathContextPtr ctxt,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing vendor string for CPU vendor %s"), _("Missing vendor string for CPU vendor %s"),
vendor->name); vendor->name);
goto cleanup; goto error;
} }
if (strlen(string) != VENDOR_STRING_LENGTH) { if (strlen(string) != VENDOR_STRING_LENGTH) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid CPU vendor string '%s'"), string); _("Invalid CPU vendor string '%s'"), string);
goto cleanup; goto error;
} }
vendor->cpuid.function = 0; vendor->cpuid.function = 0;
...@@ -558,15 +558,37 @@ x86VendorLoad(xmlXPathContextPtr ctxt, ...@@ -558,15 +558,37 @@ x86VendorLoad(xmlXPathContextPtr ctxt,
vendor->cpuid.edx = virReadBufInt32LE(string + 4); vendor->cpuid.edx = virReadBufInt32LE(string + 4);
vendor->cpuid.ecx = virReadBufInt32LE(string + 8); vendor->cpuid.ecx = virReadBufInt32LE(string + 8);
if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0)
goto cleanup;
ret = 0;
cleanup: cleanup:
VIR_FREE(string); VIR_FREE(string);
return vendor;
error:
x86VendorFree(vendor); x86VendorFree(vendor);
return ret; vendor = NULL;
goto cleanup;
}
static int
x86VendorsLoad(virCPUx86MapPtr map,
xmlXPathContextPtr ctxt,
xmlNodePtr *nodes,
int n)
{
virCPUx86VendorPtr vendor;
size_t i;
if (VIR_ALLOC_N(map->vendors, n) < 0)
return -1;
for (i = 0; i < n; i++) {
ctxt->node = nodes[i];
if (!(vendor = x86VendorParse(ctxt, map)))
return -1;
map->vendors[map->nvendors++] = vendor;
}
return 0;
} }
...@@ -670,43 +692,41 @@ x86ParseCPUID(xmlXPathContextPtr ctxt, ...@@ -670,43 +692,41 @@ x86ParseCPUID(xmlXPathContextPtr ctxt,
} }
static int static virCPUx86FeaturePtr
x86FeatureLoad(xmlXPathContextPtr ctxt, x86FeatureParse(xmlXPathContextPtr ctxt,
virCPUx86MapPtr map) virCPUx86MapPtr map)
{ {
xmlNodePtr *nodes = NULL; xmlNodePtr *nodes = NULL;
xmlNodePtr ctxt_node = ctxt->node;
virCPUx86FeaturePtr feature; virCPUx86FeaturePtr feature;
virCPUx86CPUID cpuid; virCPUx86CPUID cpuid;
int ret = -1;
size_t i; size_t i;
int n; int n;
char *str = NULL; char *str = NULL;
bool migratable = true;
if (!(feature = x86FeatureNew())) if (!(feature = x86FeatureNew()))
goto cleanup; goto error;
feature->migratable = true;
feature->name = virXPathString("string(@name)", ctxt); feature->name = virXPathString("string(@name)", ctxt);
if (!feature->name) { if (!feature->name) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Missing CPU feature name")); "%s", _("Missing CPU feature name"));
goto cleanup; goto error;
} }
if (x86FeatureFind(map, feature->name)) { if (x86FeatureFind(map, feature->name)) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("CPU feature %s already defined"), feature->name); _("CPU feature %s already defined"), feature->name);
goto cleanup; goto error;
} }
str = virXPathString("string(@migratable)", ctxt); str = virXPathString("string(@migratable)", ctxt);
if (STREQ_NULLABLE(str, "no")) if (STREQ_NULLABLE(str, "no"))
migratable = false; feature->migratable = false;
n = virXPathNodeSet("./cpuid", ctxt, &nodes); n = virXPathNodeSet("./cpuid", ctxt, &nodes);
if (n < 0) if (n < 0)
goto cleanup; goto error;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
ctxt->node = nodes[i]; ctxt->node = nodes[i];
...@@ -714,32 +734,51 @@ x86FeatureLoad(xmlXPathContextPtr ctxt, ...@@ -714,32 +734,51 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid cpuid[%zu] in %s feature"), _("Invalid cpuid[%zu] in %s feature"),
i, feature->name); i, feature->name);
goto cleanup; goto error;
} }
if (virCPUx86DataAddCPUID(feature->data, &cpuid)) if (virCPUx86DataAddCPUID(feature->data, &cpuid))
goto cleanup; goto error;
} }
if (!migratable &&
VIR_APPEND_ELEMENT_COPY(map->migrate_blockers,
map->nblockers, feature) < 0)
goto cleanup;
if (VIR_APPEND_ELEMENT(map->features, map->nfeatures, feature) < 0)
goto cleanup;
ret = 0;
cleanup: cleanup:
x86FeatureFree(feature);
ctxt->node = ctxt_node;
VIR_FREE(nodes); VIR_FREE(nodes);
VIR_FREE(str); VIR_FREE(str);
return feature;
return ret; error:
x86FeatureFree(feature);
feature = NULL;
goto cleanup;
} }
static int
x86FeaturesLoad(virCPUx86MapPtr map,
xmlXPathContextPtr ctxt,
xmlNodePtr *nodes,
int n)
{
virCPUx86FeaturePtr feature;
size_t i;
if (VIR_ALLOC_N(map->features, n) < 0)
return -1;
for (i = 0; i < n; i++) {
ctxt->node = nodes[i];
if (!(feature = x86FeatureParse(ctxt, map)))
return -1;
map->features[map->nfeatures++] = feature;
if (!feature->migratable &&
VIR_APPEND_ELEMENT(map->migrate_blockers,
map->nblockers,
feature) < 0)
return -1;
}
return 0;
}
static virCPUx86Data * static virCPUx86Data *
x86DataFromCPUFeatures(virCPUDefPtr cpu, x86DataFromCPUFeatures(virCPUDefPtr cpu,
virCPUx86MapPtr map) virCPUx86MapPtr map)
...@@ -960,25 +999,24 @@ x86ModelCompare(virCPUx86ModelPtr model1, ...@@ -960,25 +999,24 @@ x86ModelCompare(virCPUx86ModelPtr model1,
} }
static int static virCPUx86ModelPtr
x86ModelLoad(xmlXPathContextPtr ctxt, x86ModelParse(xmlXPathContextPtr ctxt,
virCPUx86MapPtr map) virCPUx86MapPtr map)
{ {
xmlNodePtr *nodes = NULL; xmlNodePtr *nodes = NULL;
virCPUx86ModelPtr model; virCPUx86ModelPtr model;
char *vendor = NULL; char *vendor = NULL;
int ret = -1;
size_t i; size_t i;
int n; int n;
if (!(model = x86ModelNew())) if (!(model = x86ModelNew()))
goto cleanup; goto error;
model->name = virXPathString("string(@name)", ctxt); model->name = virXPathString("string(@name)", ctxt);
if (!model->name) { if (!model->name) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Missing CPU model name")); "%s", _("Missing CPU model name"));
goto cleanup; goto error;
} }
if (virXPathNode("./model", ctxt)) { if (virXPathNode("./model", ctxt)) {
...@@ -990,7 +1028,7 @@ x86ModelLoad(xmlXPathContextPtr ctxt, ...@@ -990,7 +1028,7 @@ x86ModelLoad(xmlXPathContextPtr ctxt,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing ancestor's name in CPU model %s"), _("Missing ancestor's name in CPU model %s"),
model->name); model->name);
goto cleanup; goto error;
} }
if (!(ancestor = x86ModelFind(map, name))) { if (!(ancestor = x86ModelFind(map, name))) {
...@@ -998,7 +1036,7 @@ x86ModelLoad(xmlXPathContextPtr ctxt, ...@@ -998,7 +1036,7 @@ x86ModelLoad(xmlXPathContextPtr ctxt,
_("Ancestor model %s not found for CPU model %s"), _("Ancestor model %s not found for CPU model %s"),
name, model->name); name, model->name);
VIR_FREE(name); VIR_FREE(name);
goto cleanup; goto error;
} }
VIR_FREE(name); VIR_FREE(name);
...@@ -1006,7 +1044,7 @@ x86ModelLoad(xmlXPathContextPtr ctxt, ...@@ -1006,7 +1044,7 @@ x86ModelLoad(xmlXPathContextPtr ctxt,
model->vendor = ancestor->vendor; model->vendor = ancestor->vendor;
virCPUx86DataFree(model->data); virCPUx86DataFree(model->data);
if (!(model->data = x86DataCopy(ancestor->data))) if (!(model->data = x86DataCopy(ancestor->data)))
goto cleanup; goto error;
} }
if (virXPathBoolean("boolean(./vendor)", ctxt)) { if (virXPathBoolean("boolean(./vendor)", ctxt)) {
...@@ -1015,20 +1053,20 @@ x86ModelLoad(xmlXPathContextPtr ctxt, ...@@ -1015,20 +1053,20 @@ x86ModelLoad(xmlXPathContextPtr ctxt,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid vendor element in CPU model %s"), _("Invalid vendor element in CPU model %s"),
model->name); model->name);
goto cleanup; goto error;
} }
if (!(model->vendor = x86VendorFind(map, vendor))) { if (!(model->vendor = x86VendorFind(map, vendor))) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown vendor %s referenced by CPU model %s"), _("Unknown vendor %s referenced by CPU model %s"),
vendor, model->name); vendor, model->name);
goto cleanup; goto error;
} }
} }
n = virXPathNodeSet("./feature", ctxt, &nodes); n = virXPathNodeSet("./feature", ctxt, &nodes);
if (n < 0) if (n < 0)
goto cleanup; goto error;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
virCPUx86FeaturePtr feature; virCPUx86FeaturePtr feature;
...@@ -1037,7 +1075,7 @@ x86ModelLoad(xmlXPathContextPtr ctxt, ...@@ -1037,7 +1075,7 @@ x86ModelLoad(xmlXPathContextPtr ctxt,
if (!(name = virXMLPropString(nodes[i], "name"))) { if (!(name = virXMLPropString(nodes[i], "name"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing feature name for CPU model %s"), model->name); _("Missing feature name for CPU model %s"), model->name);
goto cleanup; goto error;
} }
if (!(feature = x86FeatureFind(map, name))) { if (!(feature = x86FeatureFind(map, name))) {
...@@ -1045,24 +1083,46 @@ x86ModelLoad(xmlXPathContextPtr ctxt, ...@@ -1045,24 +1083,46 @@ x86ModelLoad(xmlXPathContextPtr ctxt,
_("Feature %s required by CPU model %s not found"), _("Feature %s required by CPU model %s not found"),
name, model->name); name, model->name);
VIR_FREE(name); VIR_FREE(name);
goto cleanup; goto error;
} }
VIR_FREE(name); VIR_FREE(name);
if (x86DataAdd(model->data, feature->data)) if (x86DataAdd(model->data, feature->data))
goto cleanup; goto error;
} }
if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0)
goto cleanup;
ret = 0;
cleanup: cleanup:
x86ModelFree(model);
VIR_FREE(vendor); VIR_FREE(vendor);
VIR_FREE(nodes); VIR_FREE(nodes);
return ret; return model;
error:
x86ModelFree(model);
model = NULL;
goto cleanup;
}
static int
x86ModelsLoad(virCPUx86MapPtr map,
xmlXPathContextPtr ctxt,
xmlNodePtr *nodes,
int n)
{
virCPUx86ModelPtr model;
size_t i;
if (VIR_ALLOC_N(map->models, n) < 0)
return -1;
for (i = 0; i < n; i++) {
ctxt->node = nodes[i];
if (!(model = x86ModelParse(ctxt, map)))
return -1;
map->models[map->nmodels++] = model;
}
return 0;
} }
...@@ -1098,17 +1158,19 @@ x86MapFree(virCPUx86MapPtr map) ...@@ -1098,17 +1158,19 @@ x86MapFree(virCPUx86MapPtr map)
static int static int
x86MapLoadCallback(cpuMapElement element, x86MapLoadCallback(cpuMapElement element,
xmlXPathContextPtr ctxt, xmlXPathContextPtr ctxt,
xmlNodePtr *nodes,
int n,
void *data) void *data)
{ {
virCPUx86MapPtr map = data; virCPUx86MapPtr map = data;
switch (element) { switch (element) {
case CPU_MAP_ELEMENT_VENDOR: case CPU_MAP_ELEMENT_VENDOR:
return x86VendorLoad(ctxt, map); return x86VendorsLoad(map, ctxt, nodes, n);
case CPU_MAP_ELEMENT_FEATURE: case CPU_MAP_ELEMENT_FEATURE:
return x86FeatureLoad(ctxt, map); return x86FeaturesLoad(map, ctxt, nodes, n);
case CPU_MAP_ELEMENT_MODEL: case CPU_MAP_ELEMENT_MODEL:
return x86ModelLoad(ctxt, map); return x86ModelsLoad(map, ctxt, nodes, n);
case CPU_MAP_ELEMENT_LAST: case CPU_MAP_ELEMENT_LAST:
break; break;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册