提交 6b159239 编写于 作者: J Jiri Denemark

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: NJiri Denemark <jdenemar@redhat.com>
上级 0b119e2b
......@@ -809,3 +809,62 @@ cpuGetModels(virArch arch, char ***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
(*cpuArchGetModels) (char ***models);
typedef int
(*virCPUArchTranslate)(virCPUDefPtr cpu,
const char **models,
unsigned int nmodels);
struct cpuArchDriver {
const char *name;
const virArch *arch;
......@@ -119,6 +124,7 @@ struct cpuArchDriver {
cpuArchDataFormat dataFormat;
cpuArchDataParse dataParse;
cpuArchGetModels getModels;
virCPUArchTranslate translate;
};
......@@ -202,6 +208,14 @@ cpuModelIsAllowed(const char *model,
int
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
* 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 = {
.name = "x86",
.arch = archs,
......@@ -2663,4 +2713,5 @@ struct cpuArchDriver cpuDriverX86 = {
.dataFormat = x86CPUDataFormat,
.dataParse = x86CPUDataParse,
.getModels = x86GetModels,
.translate = virCPUx86Translate,
};
......@@ -981,6 +981,7 @@ cpuGetModels;
cpuGuestData;
cpuHasFeature;
cpuNodeData;
virCPUTranslate;
virCPUUpdate;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册