From b9a2552d2ae2577aa80ded2342b63e569a3a7fdc Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Thu, 15 Apr 2010 12:06:13 +0200 Subject: [PATCH] Use configured CPU model if possible 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. --- src/cpu/cpu.c | 8 +++++--- src/cpu/cpu.h | 6 ++++-- src/cpu/cpu_x86.c | 11 +++++++++-- src/qemu/qemu_conf.c | 10 ++++++++-- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 4a1588d043..580b767b9a 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -127,11 +127,13 @@ int 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++) @@ -160,7 +162,7 @@ cpuDecode(virCPUDefPtr cpu, return -1; } - return driver->decode(cpu, data, models, nmodels); + return driver->decode(cpu, data, models, nmodels, preferred); } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 1494a7f7d4..40f2a7d9cf 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -49,7 +49,8 @@ typedef int (*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, @@ -108,7 +109,8 @@ extern int 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, diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index b2ca8c831a..633eb69e55 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -1064,7 +1064,8 @@ static int 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; @@ -1109,6 +1110,12 @@ x86Decode(virCPUDefPtr cpu, } } + if (preferred && STREQ(cpuCandidate->model, preferred)) { + virCPUDefFree(cpuModel); + cpuModel = cpuCandidate; + break; + } + if (cpuModel == NULL || cpuModel->nfeatures > cpuCandidate->nfeatures) { virCPUDefFree(cpuModel); @@ -1356,7 +1363,7 @@ x86Baseline(virCPUDefPtr *cpus, 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: diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 262eb5a8e2..2cbcc4fc05 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1029,7 +1029,7 @@ qemudCapsInitCPU(virCapsPtr caps, 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; @@ -3292,6 +3292,7 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, if (ncpus > 0 && host) { virCPUCompareResult cmp; + const char *preferred; cmp = cpuGuestData(host, def->cpu, &data); switch (cmp) { @@ -3309,8 +3310,13 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, 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);