qemu: Do not drop unknown CPU features from domain XML

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Jiri Denemark 2024-10-08 12:26:41 +02:00
parent aae8a5774b
commit 00e55059e6
2 changed files with 12 additions and 33 deletions

View File

@ -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:

View File

@ -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;
}