Adds ability to provide a preferred CPU model for CPUID data decoding.
Such model would be considered as the best possible model (if it's
supported by hypervisor) regardless on number of features which have to
be added or removed for describing required CPU.
cpuDecode(virCPUDefPtr cpu,
const union cpuData *data,
const char **models,
- unsigned int nmodels)
+ unsigned int nmodels,
+ const char *preferred)
{
struct cpuArchDriver *driver;
- VIR_DEBUG("cpu=%p, data=%p, nmodels=%u", cpu, data, nmodels);
+ VIR_DEBUG("cpu=%p, data=%p, nmodels=%u, preferred=%s",
+ cpu, data, nmodels, NULLSTR(preferred));
if (models) {
unsigned int i;
for (i = 0; i < nmodels; i++)
return -1;
}
- return driver->decode(cpu, data, models, nmodels);
+ return driver->decode(cpu, data, models, nmodels, preferred);
}
(*cpuArchDecode) (virCPUDefPtr cpu,
const union cpuData *data,
const char **models,
- unsigned int nmodels);
+ unsigned int nmodels,
+ const char *preferred);
typedef int
(*cpuArchEncode) (const virCPUDefPtr cpu,
cpuDecode (virCPUDefPtr cpu,
const union cpuData *data,
const char **models,
- unsigned int nmodels);
+ unsigned int nmodels,
+ const char *preferred);
extern int
cpuEncode (const char *arch,
x86Decode(virCPUDefPtr cpu,
const union cpuData *data,
const char **models,
- unsigned int nmodels)
+ unsigned int nmodels,
+ const char *preferred)
{
int ret = -1;
struct x86_map *map;
}
}
+ if (preferred && STREQ(cpuCandidate->model, preferred)) {
+ virCPUDefFree(cpuModel);
+ cpuModel = cpuCandidate;
+ break;
+ }
+
if (cpuModel == NULL
|| cpuModel->nfeatures > cpuCandidate->nfeatures) {
virCPUDefFree(cpuModel);
if (!(data = x86DataFromModel(base_model)))
goto no_memory;
- if (x86Decode(cpu, data, models, nmodels) < 0)
+ if (x86Decode(cpu, data, models, nmodels, NULL) < 0)
goto error;
cleanup:
cpu->threads = nodeinfo.threads;
if (!(data = cpuNodeData(arch))
- || cpuDecode(cpu, data, NULL, 0) < 0)
+ || cpuDecode(cpu, data, NULL, 0, NULL) < 0)
goto error;
caps->host.cpu = cpu;
if (ncpus > 0 && host) {
virCPUCompareResult cmp;
+ const char *preferred;
cmp = cpuGuestData(host, def->cpu, &data);
switch (cmp) {
if (VIR_ALLOC(guest) < 0 || !(guest->arch = strdup(ut->machine)))
goto no_memory;
+ if (def->cpu->match == VIR_CPU_MATCH_MINIMUM)
+ preferred = host->model;
+ else
+ preferred = def->cpu->model;
+
guest->type = VIR_CPU_TYPE_GUEST;
- if (cpuDecode(guest, data, cpus, ncpus) < 0)
+ if (cpuDecode(guest, data, cpus, ncpus, preferred) < 0)
goto cleanup;
virBufferVSprintf(&buf, "%s", guest->model);