From 54f60ef9af660c867146c6f9eba65c7a52a26e00 Mon Sep 17 00:00:00 2001 From: Andrea Bolognani Date: Fri, 11 Oct 2019 10:05:59 +0200 Subject: [PATCH] qemu: Validate ARM CPU features This introduces semantic validation for SVE-related features, preventing the user from combining them in invalid ways; it also automatically enables overall SVE support if any SVE vector length has been enabled by the user to make sure QEMU behaves correctly. Signed-off-by: Andrea Bolognani Tested-by: Andrew Jones Reviewed-by: Michal Privoznik --- src/qemu/qemu_domain.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 667cc89072..bda357ceb9 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)