CPU features with policy='disable' which are unknown to QEMU may be safely skipped when generating the -cpu command line, but we should still keep them in the domain definition so that we can properly check they are disabled after migrating the domain to a newer QEMU. Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- src/qemu/qemu_command.c | 13 ++++++++++++- src/qemu/qemu_process.c | 32 -------------------------------- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a0c9e5f8b3..b4888a5822 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6095,6 +6095,7 @@ qemuBuildCpuModelArgStr(virQEMUDriver *driver, { size_t i; virCPUDef *cpu = def->cpu; + g_auto(GStrv) knownFeatures = NULL; switch ((virCPUMode) cpu->mode) { case VIR_CPU_MODE_HOST_PASSTHROUGH: @@ -6153,9 +6154,14 @@ qemuBuildCpuModelArgStr(virQEMUDriver *driver, if (cpu->vendor_id) virBufferAsprintf(buf, ",vendor=%s", cpu->vendor_id); + if (ARCH_IS_X86(def->os.arch) && + virQEMUCapsGetCPUFeatures(qemuCaps, def->virtType, false, &knownFeatures) < 0) + return -1; + for (i = 0; i < cpu->nfeatures; i++) { const char *featname = virQEMUCapsCPUFeatureToQEMU(def->os.arch, cpu->features[i].name); + switch ((virCPUFeaturePolicy) cpu->features[i].policy) { case VIR_CPU_FEATURE_FORCE: case VIR_CPU_FEATURE_REQUIRE: @@ -6164,7 +6170,12 @@ qemuBuildCpuModelArgStr(virQEMUDriver *driver, case VIR_CPU_FEATURE_DISABLE: case VIR_CPU_FEATURE_FORBID: - virBufferAsprintf(buf, ",%s=off", featname); + /* Features unknown to QEMU are implicitly disabled and we can just + * skip them. */ + if (!knownFeatures || + g_strv_contains((const char **) knownFeatures, cpu->features[i].name)) { + virBufferAsprintf(buf, ",%s=off", featname); + } break; case VIR_CPU_FEATURE_OPTIONAL: diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index a00066e88e..0e9e1a8efc 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6212,26 +6212,6 @@ qemuProcessSetupHotpluggableVcpus(virDomainObj *vm, } -static bool -qemuProcessDropUnknownCPUFeatures(const char *name, - virCPUFeaturePolicy policy, - void *opaque) -{ - const char **features = opaque; - - if (policy != VIR_CPU_FEATURE_DISABLE && - policy != VIR_CPU_FEATURE_FORBID) - return true; - - if (g_strv_contains(features, name)) - return true; - - /* Features unknown to QEMU are implicitly disabled, we can just drop them - * from the definition. */ - return false; -} - - static int qemuProcessUpdateGuestCPU(virDomainDef *def, virQEMUCaps *qemuCaps, @@ -6325,18 +6305,6 @@ qemuProcessUpdateGuestCPU(virDomainDef *def, &def->os.arch) < 0) return -1; - if (ARCH_IS_X86(def->os.arch)) { - g_auto(GStrv) features = NULL; - - if (virQEMUCapsGetCPUFeatures(qemuCaps, def->virtType, false, &features) < 0) - return -1; - - if (features && - virCPUDefFilterFeatures(def->cpu, qemuProcessDropUnknownCPUFeatures, - features) < 0) - return -1; - } - return 0; } -- 2.46.2