]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Validate ARM CPU features
authorAndrea Bolognani <abologna@redhat.com>
Fri, 11 Oct 2019 08:05:59 +0000 (10:05 +0200)
committerAndrea Bolognani <abologna@redhat.com>
Thu, 7 Nov 2019 15:09:20 +0000 (16:09 +0100)
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 <abologna@redhat.com>
Tested-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_domain.c

index 667cc8907281a4d646ded2d06c2e4b7234a95106..bda357ceb96543ab292a130b430687f9d4df6cbb 100644 (file)
@@ -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)