mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 19:41:16 +00:00
cpu: Introduce virCPUTranslate
The API is supposed to make sure the provided CPU definition does not use a CPU model which is not supported by the hypervisor (if at all possible, of course). Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
0b119e2b19
commit
6b159239cc
@ -809,3 +809,62 @@ cpuGetModels(virArch arch, char ***models)
|
|||||||
|
|
||||||
return driver->getModels(models);
|
return driver->getModels(models);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virCPUTranslate:
|
||||||
|
*
|
||||||
|
* @arch: CPU architecture
|
||||||
|
* @cpu: CPU definition to be translated
|
||||||
|
* @models: NULL-terminated list of allowed CPU models (NULL if all are allowed)
|
||||||
|
* @nmodels: number of CPU models in @models
|
||||||
|
*
|
||||||
|
* Translates @cpu model (if allowed by @cpu->fallback) to a closest CPU model
|
||||||
|
* from @models list.
|
||||||
|
*
|
||||||
|
* The function does nothing (and returns 0) if @cpu does not have to be
|
||||||
|
* translated.
|
||||||
|
*
|
||||||
|
* Returns -1 on error, 0 on success.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virCPUTranslate(virArch arch,
|
||||||
|
virCPUDefPtr cpu,
|
||||||
|
char **models,
|
||||||
|
unsigned int nmodels)
|
||||||
|
{
|
||||||
|
struct cpuArchDriver *driver;
|
||||||
|
|
||||||
|
VIR_DEBUG("arch=%s, cpu=%p, model=%s, models=%p, nmodels=%u",
|
||||||
|
virArchToString(arch), cpu, NULLSTR(cpu->model), models, nmodels);
|
||||||
|
|
||||||
|
if (!(driver = cpuGetSubDriver(arch)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (cpu->mode == VIR_CPU_MODE_HOST_MODEL ||
|
||||||
|
cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (cpuModelIsAllowed(cpu->model, (const char **) models, nmodels))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (cpu->fallback != VIR_CPU_FALLBACK_ALLOW) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("CPU model %s is not supported by hypervisor"),
|
||||||
|
cpu->model);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!driver->translate) {
|
||||||
|
virReportError(VIR_ERR_NO_SUPPORT,
|
||||||
|
_("cannot translate CPU model %s to a supported model"),
|
||||||
|
cpu->model);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (driver->translate(cpu, (const char **) models, nmodels) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
VIR_DEBUG("model=%s", NULLSTR(cpu->model));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -103,6 +103,11 @@ typedef virCPUDataPtr
|
|||||||
typedef int
|
typedef int
|
||||||
(*cpuArchGetModels) (char ***models);
|
(*cpuArchGetModels) (char ***models);
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*virCPUArchTranslate)(virCPUDefPtr cpu,
|
||||||
|
const char **models,
|
||||||
|
unsigned int nmodels);
|
||||||
|
|
||||||
struct cpuArchDriver {
|
struct cpuArchDriver {
|
||||||
const char *name;
|
const char *name;
|
||||||
const virArch *arch;
|
const virArch *arch;
|
||||||
@ -119,6 +124,7 @@ struct cpuArchDriver {
|
|||||||
cpuArchDataFormat dataFormat;
|
cpuArchDataFormat dataFormat;
|
||||||
cpuArchDataParse dataParse;
|
cpuArchDataParse dataParse;
|
||||||
cpuArchGetModels getModels;
|
cpuArchGetModels getModels;
|
||||||
|
virCPUArchTranslate translate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -202,6 +208,14 @@ cpuModelIsAllowed(const char *model,
|
|||||||
int
|
int
|
||||||
cpuGetModels(virArch arch, char ***models);
|
cpuGetModels(virArch arch, char ***models);
|
||||||
|
|
||||||
|
int
|
||||||
|
virCPUTranslate(virArch arch,
|
||||||
|
virCPUDefPtr cpu,
|
||||||
|
char **models,
|
||||||
|
unsigned int nmodels)
|
||||||
|
ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
|
|
||||||
/* cpuDataFormat and cpuDataParse are implemented for unit tests only and
|
/* cpuDataFormat and cpuDataParse are implemented for unit tests only and
|
||||||
* have no real-life usage
|
* have no real-life usage
|
||||||
*/
|
*/
|
||||||
|
@ -2643,6 +2643,56 @@ x86GetModels(char ***models)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virCPUx86Translate(virCPUDefPtr cpu,
|
||||||
|
const char **models,
|
||||||
|
unsigned int nmodels)
|
||||||
|
{
|
||||||
|
virCPUDefPtr translated = NULL;
|
||||||
|
virCPUx86MapPtr map;
|
||||||
|
virCPUx86ModelPtr model = NULL;
|
||||||
|
size_t i;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!(map = virCPUx86GetMap()))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(model = x86ModelFromCPU(cpu, map, -1)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (model->vendor &&
|
||||||
|
virCPUx86DataAddCPUID(&model->data, &model->vendor->cpuid) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (x86DataAddSignature(&model->data, model->signature) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(translated = virCPUDefCopyWithoutModel(cpu)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (VIR_STRDUP(translated->vendor, cpu->vendor) < 0 ||
|
||||||
|
VIR_STRDUP(translated->vendor_id, cpu->vendor_id) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (x86Decode(translated, &model->data, models, nmodels, NULL, 0) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (i = 0; i < cpu->nfeatures; i++) {
|
||||||
|
virCPUFeatureDefPtr f = cpu->features + i;
|
||||||
|
if (virCPUDefUpdateFeature(translated, f->name, f->policy) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
virCPUDefStealModel(cpu, translated);
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virCPUDefFree(translated);
|
||||||
|
x86ModelFree(model);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct cpuArchDriver cpuDriverX86 = {
|
struct cpuArchDriver cpuDriverX86 = {
|
||||||
.name = "x86",
|
.name = "x86",
|
||||||
.arch = archs,
|
.arch = archs,
|
||||||
@ -2663,4 +2713,5 @@ struct cpuArchDriver cpuDriverX86 = {
|
|||||||
.dataFormat = x86CPUDataFormat,
|
.dataFormat = x86CPUDataFormat,
|
||||||
.dataParse = x86CPUDataParse,
|
.dataParse = x86CPUDataParse,
|
||||||
.getModels = x86GetModels,
|
.getModels = x86GetModels,
|
||||||
|
.translate = virCPUx86Translate,
|
||||||
};
|
};
|
||||||
|
@ -981,6 +981,7 @@ cpuGetModels;
|
|||||||
cpuGuestData;
|
cpuGuestData;
|
||||||
cpuHasFeature;
|
cpuHasFeature;
|
||||||
cpuNodeData;
|
cpuNodeData;
|
||||||
|
virCPUTranslate;
|
||||||
virCPUUpdate;
|
virCPUUpdate;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user