{
size_t i;
virCPUDef *cpu = def->cpu;
+ g_auto(GStrv) knownFeatures = NULL;
switch ((virCPUMode) cpu->mode) {
case VIR_CPU_MODE_HOST_PASSTHROUGH:
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:
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:
}
-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,
&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;
}