diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml index ba8c17dfe4..6d51283a86 100644 --- a/src/cpu/cpu_map.xml +++ b/src/cpu/cpu_map.xml @@ -591,12 +591,17 @@ + + + + + diff --git a/src/cpu/cpu_powerpc.c b/src/cpu/cpu_powerpc.c index fc05ea0609..162707f3aa 100644 --- a/src/cpu/cpu_powerpc.c +++ b/src/cpu/cpu_powerpc.c @@ -38,20 +38,6 @@ static const virArch archs[] = { VIR_ARCH_PPC64 }; -struct cpuPowerPC { - const char *name; - const char *vendor; - uint32_t pvr; -}; - -static const struct cpuPowerPC cpu_defs[] = { - {"POWER7", "IBM", 0x003f0200}, - {"POWER7_v2.1", "IBM", 0x003f0201}, - {"POWER7_v2.3", "IBM", 0x003f0203}, - {NULL, NULL, 0xffffffff} -}; - - struct ppc_vendor { char *name; struct ppc_vendor *next; @@ -60,7 +46,7 @@ struct ppc_vendor { struct ppc_model { char *name; const struct ppc_vendor *vendor; - union cpuData *data; + struct cpuPPCData data; struct ppc_model *next; }; @@ -69,59 +55,6 @@ struct ppc_map { struct ppc_model *models; }; -static int -ConvertModelVendorFromPVR(char **model, - char **vendor, - uint32_t pvr) -{ - int i; - - for (i = 0; cpu_defs[i].name; i++) { - if (cpu_defs[i].pvr == pvr) { - *model = strdup(cpu_defs[i].name); - *vendor = strdup(cpu_defs[i].vendor); - return 0; - } - } - - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("Missing the definition of this model")); - return -1; -} - -static int -ConvertPVRFromModel(const char *model, - uint32_t *pvr) -{ - int i; - - for (i = 0; cpu_defs[i].name; i++) { - if (STREQ(cpu_defs[i].name, model)) { - *pvr = cpu_defs[i].pvr; - return 0; - } - } - - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("Missing the definition of this model")); - return -1; -} - -static struct ppc_model * -ppcModelNew(void) -{ - struct ppc_model *model; - - if (VIR_ALLOC(model) < 0) - return NULL; - - if (VIR_ALLOC(model->data) < 0) { - VIR_FREE(model); - return NULL; - } - - return model; -} static void ppcModelFree(struct ppc_model *model) @@ -130,9 +63,6 @@ ppcModelFree(struct ppc_model *model) return; VIR_FREE(model->name); - - VIR_FREE(model->data); - VIR_FREE(model); } @@ -153,6 +83,23 @@ ppcModelFind(const struct ppc_map *map, return NULL; } +static struct ppc_model * +ppcModelFindPVR(const struct ppc_map *map, + uint32_t pvr) +{ + struct ppc_model *model; + + model = map->models; + while (model != NULL) { + if (model->data.pvr == pvr) + return model; + + model = model->next; + } + + return NULL; +} + static struct ppc_vendor * ppcVendorFind(const struct ppc_map *map, const char *name) @@ -223,25 +170,27 @@ static int ppcModelLoad(xmlXPathContextPtr ctxt, struct ppc_map *map) { - xmlNodePtr *nodes = NULL; struct ppc_model *model; char *vendor = NULL; - int ret = -1; + unsigned long pvr; - if (!(model = ppcModelNew())) - goto no_memory; + if (VIR_ALLOC(model) < 0) { + virReportOOMError(); + return -1; + } model->name = virXPathString("string(@name)", ctxt); - if (model->name == NULL) { + if (!model->name) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing CPU model name")); goto ignore; } - ret = ConvertPVRFromModel(model->name, &model->data->ppc.pvr); - if (ret < 0) - goto ignore; - + if (ppcModelFind(map, model->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU model %s already defined"), model->name); + goto ignore; + } if (virXPathBoolean("boolean(./vendor)", ctxt)) { vendor = virXPathString("string(./vendor/@name)", ctxt); @@ -260,26 +209,29 @@ ppcModelLoad(xmlXPathContextPtr ctxt, } } - if (map->models == NULL) + if (!virXPathBoolean("boolean(./pvr)", ctxt) || + virXPathULongHex("string(./pvr/@value)", ctxt, &pvr) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing or invalid PVR value in CPU model %s"), + model->name); + goto ignore; + } + model->data.pvr = pvr; + + if (map->models == NULL) { map->models = model; - else { + } else { model->next = map->models; map->models = model; } - ret = 0; - -out: +cleanup: VIR_FREE(vendor); - VIR_FREE(nodes); - return ret; - -no_memory: - virReportOOMError(); + return 0; ignore: ppcModelFree(model); - goto out; + goto cleanup; } static int @@ -294,7 +246,8 @@ ppcMapLoadCallback(enum cpuMapElement element, return ppcVendorLoad(ctxt, map); case CPU_MAP_ELEMENT_MODEL: return ppcModelLoad(ctxt, map); - default: + case CPU_MAP_ELEMENT_FEATURE: + case CPU_MAP_ELEMENT_LAST: break; } @@ -362,32 +315,34 @@ ppcDecode(virCPUDefPtr cpu, { int ret = -1; struct ppc_map *map; - char *cpu_vendor = NULL; - char *cpu_model = NULL; + const struct ppc_model *model; if (data == NULL || (map = ppcLoadMap()) == NULL) return -1; - if (ConvertModelVendorFromPVR(&cpu_model, &cpu_vendor, data->ppc.pvr) < 0) - goto cleanup; - - if (!cpuModelIsAllowed(cpu_model, models, nmodels)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("CPU model %s is not supported by hypervisor"), - cpu_model); + if (!(model = ppcModelFindPVR(map, data->ppc.pvr))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU model with PVR 0x%08x"), + data->ppc.pvr); goto cleanup; } - cpu->model = cpu_model; - cpu->vendor = cpu_vendor; - cpu_model = NULL; - cpu_vendor = NULL; + if (!cpuModelIsAllowed(model->name, models, nmodels)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU model %s is not supported by hypervisor"), + model->name); + goto cleanup; + } + + if (!(cpu->model = strdup(model->name)) || + (model->vendor && !(cpu->vendor = strdup(model->vendor->name)))) { + virReportOOMError(); + goto cleanup; + } ret = 0; cleanup: - VIR_FREE(cpu_model); - VIR_FREE(cpu_vendor); ppcMapFree(map); return ret;