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 4a1588d..580b767 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 1494a7f..40f2a7d 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 014fe7d..90ea509 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 a1392fa..e6e6490 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);
--
1.7.0.4