diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 9b7dde66e78a6f313a85f4dbde8705d14a6681b8..4cf4069d50ac6e5097f7165803995e3635a4ce36 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6047,6 +6047,26 @@ qemuProcessSetupHotpluggableVcpus(virQEMUDriverPtr driver, } +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 (virStringListHasString(features, name)) + return true; + + /* Features unknown to QEMU are implicitly disabled, we can just drop them + * from the definition. */ + return false; +} + + static int qemuProcessUpdateGuestCPU(virDomainDefPtr def, virQEMUCapsPtr qemuCaps, @@ -6112,6 +6132,18 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def, &def->os.arch) < 0) return -1; + if (ARCH_IS_X86(def->os.arch)) { + VIR_AUTOSTRINGLIST features = NULL; + + if (virQEMUCapsGetCPUFeatures(qemuCaps, def->virtType, false, &features) < 0) + return -1; + + if (features && + virCPUDefFilterFeatures(def->cpu, qemuProcessDropUnknownCPUFeatures, + features) < 0) + return -1; + } + return 0; } diff --git a/tests/qemuxml2argvdata/cpu-Icelake-Server-pconfig.x86_64-latest.args b/tests/qemuxml2argvdata/cpu-Icelake-Server-pconfig.x86_64-latest.args index d6f5a0ad98eb243150689531cdc6421ebd5f0b99..88d05a482ad0081632c98bec0eb529f66e2d4eb3 100644 --- a/tests/qemuxml2argvdata/cpu-Icelake-Server-pconfig.x86_64-latest.args +++ b/tests/qemuxml2argvdata/cpu-Icelake-Server-pconfig.x86_64-latest.args @@ -13,7 +13,7 @@ QEMU_AUDIO_DRV=none \ -object secret,id=masterKey0,format=raw,\ file=/tmp/lib/domain--1-test/master-key.aes \ -machine pc,accel=kvm,usb=off,dump-guest-core=off \ --cpu Icelake-Server,pconfig=off \ +-cpu Icelake-Server \ -m 214 \ -overcommit mem-lock=off \ -smp 1,sockets=1,cores=1,threads=1 \