mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 06:35:24 +00:00
cpu: Remove hardcoded list of PowerPC models
The cpu_map.xml file is there to separate CPU model definitions from the code. Having the only interesting data for PowerPC models only in the source code. This patch moves this data to the XML file and removes the hardcoded list completely.
This commit is contained in:
parent
f42ecaf12b
commit
7a4f12381c
@ -591,12 +591,17 @@
|
|||||||
<!-- IBM-based CPU models -->
|
<!-- IBM-based CPU models -->
|
||||||
<model name='POWER7'>
|
<model name='POWER7'>
|
||||||
<vendor name='IBM'/>
|
<vendor name='IBM'/>
|
||||||
|
<pvr value='0x003f0200'/>
|
||||||
</model>
|
</model>
|
||||||
|
|
||||||
<model name='POWER7_v2.1'>
|
<model name='POWER7_v2.1'>
|
||||||
<vendor name='IBM'/>
|
<vendor name='IBM'/>
|
||||||
|
<pvr value='0x003f0201'/>
|
||||||
</model>
|
</model>
|
||||||
|
|
||||||
<model name='POWER7_v2.3'>
|
<model name='POWER7_v2.3'>
|
||||||
<vendor name='IBM'/>
|
<vendor name='IBM'/>
|
||||||
|
<pvr value='0x003f0203'/>
|
||||||
</model>
|
</model>
|
||||||
</arch>
|
</arch>
|
||||||
</cpus>
|
</cpus>
|
||||||
|
@ -38,20 +38,6 @@
|
|||||||
|
|
||||||
static const virArch archs[] = { VIR_ARCH_PPC64 };
|
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 {
|
struct ppc_vendor {
|
||||||
char *name;
|
char *name;
|
||||||
struct ppc_vendor *next;
|
struct ppc_vendor *next;
|
||||||
@ -60,7 +46,7 @@ struct ppc_vendor {
|
|||||||
struct ppc_model {
|
struct ppc_model {
|
||||||
char *name;
|
char *name;
|
||||||
const struct ppc_vendor *vendor;
|
const struct ppc_vendor *vendor;
|
||||||
union cpuData *data;
|
struct cpuPPCData data;
|
||||||
struct ppc_model *next;
|
struct ppc_model *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -69,59 +55,6 @@ struct ppc_map {
|
|||||||
struct ppc_model *models;
|
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
|
static void
|
||||||
ppcModelFree(struct ppc_model *model)
|
ppcModelFree(struct ppc_model *model)
|
||||||
@ -130,9 +63,6 @@ ppcModelFree(struct ppc_model *model)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
VIR_FREE(model->name);
|
VIR_FREE(model->name);
|
||||||
|
|
||||||
VIR_FREE(model->data);
|
|
||||||
|
|
||||||
VIR_FREE(model);
|
VIR_FREE(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +83,23 @@ ppcModelFind(const struct ppc_map *map,
|
|||||||
return NULL;
|
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 *
|
static struct ppc_vendor *
|
||||||
ppcVendorFind(const struct ppc_map *map,
|
ppcVendorFind(const struct ppc_map *map,
|
||||||
const char *name)
|
const char *name)
|
||||||
@ -223,25 +170,27 @@ static int
|
|||||||
ppcModelLoad(xmlXPathContextPtr ctxt,
|
ppcModelLoad(xmlXPathContextPtr ctxt,
|
||||||
struct ppc_map *map)
|
struct ppc_map *map)
|
||||||
{
|
{
|
||||||
xmlNodePtr *nodes = NULL;
|
|
||||||
struct ppc_model *model;
|
struct ppc_model *model;
|
||||||
char *vendor = NULL;
|
char *vendor = NULL;
|
||||||
int ret = -1;
|
unsigned long pvr;
|
||||||
|
|
||||||
if (!(model = ppcModelNew()))
|
if (VIR_ALLOC(model) < 0) {
|
||||||
goto no_memory;
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
model->name = virXPathString("string(@name)", ctxt);
|
model->name = virXPathString("string(@name)", ctxt);
|
||||||
if (model->name == NULL) {
|
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 ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ConvertPVRFromModel(model->name, &model->data->ppc.pvr);
|
if (ppcModelFind(map, model->name)) {
|
||||||
if (ret < 0)
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
goto ignore;
|
_("CPU model %s already defined"), model->name);
|
||||||
|
goto ignore;
|
||||||
|
}
|
||||||
|
|
||||||
if (virXPathBoolean("boolean(./vendor)", ctxt)) {
|
if (virXPathBoolean("boolean(./vendor)", ctxt)) {
|
||||||
vendor = virXPathString("string(./vendor/@name)", 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;
|
map->models = model;
|
||||||
else {
|
} else {
|
||||||
model->next = map->models;
|
model->next = map->models;
|
||||||
map->models = model;
|
map->models = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
cleanup:
|
||||||
|
|
||||||
out:
|
|
||||||
VIR_FREE(vendor);
|
VIR_FREE(vendor);
|
||||||
VIR_FREE(nodes);
|
return 0;
|
||||||
return ret;
|
|
||||||
|
|
||||||
no_memory:
|
|
||||||
virReportOOMError();
|
|
||||||
|
|
||||||
ignore:
|
ignore:
|
||||||
ppcModelFree(model);
|
ppcModelFree(model);
|
||||||
goto out;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -294,7 +246,8 @@ ppcMapLoadCallback(enum cpuMapElement element,
|
|||||||
return ppcVendorLoad(ctxt, map);
|
return ppcVendorLoad(ctxt, map);
|
||||||
case CPU_MAP_ELEMENT_MODEL:
|
case CPU_MAP_ELEMENT_MODEL:
|
||||||
return ppcModelLoad(ctxt, map);
|
return ppcModelLoad(ctxt, map);
|
||||||
default:
|
case CPU_MAP_ELEMENT_FEATURE:
|
||||||
|
case CPU_MAP_ELEMENT_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,32 +315,34 @@ ppcDecode(virCPUDefPtr cpu,
|
|||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
struct ppc_map *map;
|
struct ppc_map *map;
|
||||||
char *cpu_vendor = NULL;
|
const struct ppc_model *model;
|
||||||
char *cpu_model = NULL;
|
|
||||||
|
|
||||||
if (data == NULL || (map = ppcLoadMap()) == NULL)
|
if (data == NULL || (map = ppcLoadMap()) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ConvertModelVendorFromPVR(&cpu_model, &cpu_vendor, data->ppc.pvr) < 0)
|
if (!(model = ppcModelFindPVR(map, data->ppc.pvr))) {
|
||||||
goto cleanup;
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
_("Cannot find CPU model with PVR 0x%08x"),
|
||||||
if (!cpuModelIsAllowed(cpu_model, models, nmodels)) {
|
data->ppc.pvr);
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
||||||
_("CPU model %s is not supported by hypervisor"),
|
|
||||||
cpu_model);
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->model = cpu_model;
|
if (!cpuModelIsAllowed(model->name, models, nmodels)) {
|
||||||
cpu->vendor = cpu_vendor;
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
cpu_model = NULL;
|
_("CPU model %s is not supported by hypervisor"),
|
||||||
cpu_vendor = NULL;
|
model->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cpu->model = strdup(model->name)) ||
|
||||||
|
(model->vendor && !(cpu->vendor = strdup(model->vendor->name)))) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(cpu_model);
|
|
||||||
VIR_FREE(cpu_vendor);
|
|
||||||
ppcMapFree(map);
|
ppcMapFree(map);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user