diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 667cc8907281a4d646ded2d06c2e4b7234a95106..bda357ceb96543ab292a130b430687f9d4df6cbb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4465,6 +4465,10 @@ qemuDomainDefVcpusPostParse(virDomainDefPtr def) static int qemuDomainDefCPUPostParse(virDomainDefPtr def) { + virCPUFeatureDefPtr sveFeature = NULL; + bool sveVectorLengthsProvided = false; + size_t i; + if (!def->cpu) return 0; @@ -4522,6 +4526,39 @@ qemuDomainDefCPUPostParse(virDomainDefPtr def) } } + for (i = 0; i < def->cpu->nfeatures; i++) { + virCPUFeatureDefPtr feature = &def->cpu->features[i]; + + if (STREQ(feature->name, "sve")) { + sveFeature = feature; + } else if (STRPREFIX(feature->name, "sve")) { + sveVectorLengthsProvided = true; + } + } + + if (sveVectorLengthsProvided) { + if (sveFeature) { + if (sveFeature->policy == VIR_CPU_FEATURE_DISABLE || + sveFeature->policy == VIR_CPU_FEATURE_FORBID) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("SVE disabled, but SVE vector lengths provided")); + return -1; + } else { + sveFeature->policy = VIR_CPU_FEATURE_REQUIRE; + } + } else { + if (VIR_RESIZE_N(def->cpu->features, def->cpu->nfeatures_max, + def->cpu->nfeatures, 1) < 0) { + return -1; + } + + def->cpu->features[def->cpu->nfeatures].name = g_strdup("sve"); + def->cpu->features[def->cpu->nfeatures].policy = VIR_CPU_FEATURE_REQUIRE; + + def->cpu->nfeatures++; + } + } + /* Nothing to be done if only CPU topology is specified. */ if (def->cpu->mode == VIR_CPU_MODE_CUSTOM && !def->cpu->model)