459f93
From 752c74eeae67d41e7550991cb3bbe289984ec9d3 Mon Sep 17 00:00:00 2001
459f93
Message-Id: <752c74eeae67d41e7550991cb3bbe289984ec9d3@dist-git>
459f93
From: Jiri Denemark <jdenemar@redhat.com>
459f93
Date: Fri, 29 Apr 2022 10:35:02 +0200
459f93
Subject: [PATCH] cpu_x86: Ignore enabled features for input models in
459f93
 x86DecodeUseCandidate
459f93
459f93
While we don't want to aim for the shortest list of disabled features in
459f93
the baseline result (it would select a very old model), we want to do so
459f93
while looking at any of the input models for which we're trying to
459f93
compute a baseline CPU model. Given a set of input models, we always
459f93
want to take the least capable one of them (i.e., the one with shortest
459f93
list of disabled features) or a better model which is not one of the
459f93
input models.
459f93
459f93
So when considering an input model, we just check whether its list of
459f93
disabled features is shorter than the currently best one. When looking
459f93
at other models we check both enabled and disabled features while
459f93
penalizing disabled features as implemented by the previous patch.
459f93
459f93
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
459f93
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
459f93
(cherry picked from commit bb6cedd2082599323257ee0df18c93a6e0551b0b)
459f93
459f93
https://bugzilla.redhat.com/show_bug.cgi?id=1851227
459f93
459f93
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
459f93
---
459f93
 src/cpu/cpu_x86.c                             | 66 ++++++++++++-------
459f93
 ...4-baseline-Westmere+Nehalem-migratable.xml |  8 ++-
459f93
 ...86_64-baseline-Westmere+Nehalem-result.xml |  8 ++-
459f93
 ...-cpuid-baseline-Cooperlake+Cascadelake.xml | 13 ++--
459f93
 4 files changed, 64 insertions(+), 31 deletions(-)
459f93
459f93
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
459f93
index ebcd96edb1..7b59dad8bf 100644
459f93
--- a/src/cpu/cpu_x86.c
459f93
+++ b/src/cpu/cpu_x86.c
459f93
@@ -1975,7 +1975,8 @@ virCPUx86Compare(virCPUDef *host,
459f93
 
459f93
 static int
459f93
 virCPUx86CompareCandidateFeatureList(virCPUDef *cpuCurrent,
459f93
-                                     virCPUDef *cpuCandidate)
459f93
+                                     virCPUDef *cpuCandidate,
459f93
+                                     bool isPreferred)
459f93
 {
459f93
     size_t current = cpuCurrent->nfeatures;
459f93
     size_t enabledCurrent = current;
459f93
@@ -2017,6 +2018,14 @@ virCPUx86CompareCandidateFeatureList(virCPUDef *cpuCurrent,
459f93
         return 1;
459f93
     }
459f93
 
459f93
+    if (isPreferred && disabled < disabledCurrent) {
459f93
+        VIR_DEBUG("%s is in the list of preferred models and provides fewer "
459f93
+                  "disabled features than %s: %zu < %zu",
459f93
+                  cpuCandidate->model, cpuCurrent->model,
459f93
+                  disabled, disabledCurrent);
459f93
+        return 1;
459f93
+    }
459f93
+
459f93
     VIR_DEBUG("%s is not better than %s: %zu (%zu, %zu) >= %zu (%zu, %zu)",
459f93
               cpuCandidate->model, cpuCurrent->model,
459f93
               candidate, enabled, disabled,
459f93
@@ -2039,8 +2048,10 @@ x86DecodeUseCandidate(virCPUx86Model *current,
459f93
                       virCPUx86Model *candidate,
459f93
                       virCPUDef *cpuCandidate,
459f93
                       uint32_t signature,
459f93
-                      const char *preferred)
459f93
+                      const char **preferred)
459f93
 {
459f93
+    bool isPreferred = false;
459f93
+
459f93
     if (cpuCandidate->type == VIR_CPU_TYPE_HOST &&
459f93
         !candidate->decodeHost) {
459f93
         VIR_DEBUG("%s is not supposed to be used for host CPU definition",
459f93
@@ -2064,9 +2075,13 @@ x86DecodeUseCandidate(virCPUx86Model *current,
459f93
         }
459f93
     }
459f93
 
459f93
-    if (preferred && STREQ(cpuCandidate->model, preferred)) {
459f93
-        VIR_DEBUG("%s is the preferred model", cpuCandidate->model);
459f93
-        return 2;
459f93
+    if (preferred) {
459f93
+        isPreferred = g_strv_contains(preferred, cpuCandidate->model);
459f93
+
459f93
+        if (isPreferred && !preferred[1]) {
459f93
+            VIR_DEBUG("%s is the preferred model", cpuCandidate->model);
459f93
+            return 2;
459f93
+        }
459f93
     }
459f93
 
459f93
     if (!cpuCurrent) {
459f93
@@ -2093,7 +2108,8 @@ x86DecodeUseCandidate(virCPUx86Model *current,
459f93
         }
459f93
     }
459f93
 
459f93
-    return virCPUx86CompareCandidateFeatureList(cpuCurrent, cpuCandidate);
459f93
+    return virCPUx86CompareCandidateFeatureList(cpuCurrent, cpuCandidate,
459f93
+                                                isPreferred);
459f93
 }
459f93
 
459f93
 
459f93
@@ -2136,7 +2152,7 @@ static int
459f93
 x86Decode(virCPUDef *cpu,
459f93
           const virCPUx86Data *cpuData,
459f93
           virDomainCapsCPUModels *models,
459f93
-          const char *preferred,
459f93
+          const char **preferred,
459f93
           bool migratable)
459f93
 {
459f93
     virCPUx86Map *map;
459f93
@@ -2169,6 +2185,9 @@ x86Decode(virCPUDef *cpu,
459f93
 
459f93
     x86DataFilterTSX(&data, vendor, map);
459f93
 
459f93
+    if (preferred && !preferred[0])
459f93
+        preferred = NULL;
459f93
+
459f93
     /* Walk through the CPU models in reverse order to check newest
459f93
      * models first.
459f93
      */
459f93
@@ -2176,16 +2195,18 @@ x86Decode(virCPUDef *cpu,
459f93
         candidate = map->models[i];
459f93
         if (models &&
459f93
             !(hvModel = virDomainCapsCPUModelsGet(models, candidate->name))) {
459f93
-            if (preferred && STREQ(candidate->name, preferred)) {
459f93
+            if (preferred &&
459f93
+                !preferred[1] &&
459f93
+                STREQ(candidate->name, preferred[0])) {
459f93
                 if (cpu->fallback != VIR_CPU_FALLBACK_ALLOW) {
459f93
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
459f93
                                    _("CPU model %s is not supported by hypervisor"),
459f93
-                                   preferred);
459f93
+                                   preferred[0]);
459f93
                     return -1;
459f93
                 } else {
459f93
                     VIR_WARN("Preferred CPU model %s not allowed by"
459f93
                              " hypervisor; closest supported model will be"
459f93
-                             " used", preferred);
459f93
+                             " used", preferred[0]);
459f93
                 }
459f93
             } else {
459f93
                 VIR_DEBUG("CPU model %s not allowed by hypervisor; ignoring",
459f93
@@ -2793,8 +2814,8 @@ virCPUx86Baseline(virCPUDef **cpus,
459f93
     size_t i;
459f93
     virCPUx86Vendor *vendor = NULL;
459f93
     bool outputVendor = true;
459f93
-    const char *modelName;
459f93
-    bool matchingNames = true;
459f93
+    g_autofree char **modelNames = NULL;
459f93
+    size_t namesLen = 0;
459f93
     g_autoptr(virCPUData) featData = NULL;
459f93
 
459f93
     if (!(map = virCPUx86GetMap()))
459f93
@@ -2816,19 +2837,17 @@ virCPUx86Baseline(virCPUDef **cpus,
459f93
         return NULL;
459f93
     }
459f93
 
459f93
-    modelName = cpus[0]->model;
459f93
+    modelNames = g_new0(char *, ncpus + 1);
459f93
+    if (cpus[0]->model)
459f93
+        modelNames[namesLen++] = cpus[0]->model;
459f93
+
459f93
     for (i = 1; i < ncpus; i++) {
459f93
         g_autoptr(virCPUx86Model) model = NULL;
459f93
         const char *vn = NULL;
459f93
 
459f93
-        if (matchingNames && cpus[i]->model) {
459f93
-            if (!modelName) {
459f93
-                modelName = cpus[i]->model;
459f93
-            } else if (STRNEQ(modelName, cpus[i]->model)) {
459f93
-                modelName = NULL;
459f93
-                matchingNames = false;
459f93
-            }
459f93
-        }
459f93
+        if (cpus[i]->model &&
459f93
+            !g_strv_contains((const char **) modelNames, cpus[i]->model))
459f93
+            modelNames[namesLen++] = cpus[i]->model;
459f93
 
459f93
         if (!(model = x86ModelFromCPU(cpus[i], map, -1)))
459f93
             return NULL;
459f93
@@ -2891,10 +2910,11 @@ virCPUx86Baseline(virCPUDef **cpus,
459f93
         virCPUx86DataAddItem(&base_model->data, &vendor->data) < 0)
459f93
         return NULL;
459f93
 
459f93
-    if (x86Decode(cpu, &base_model->data, models, modelName, migratable) < 0)
459f93
+    if (x86Decode(cpu, &base_model->data, models,
459f93
+                  (const char **) modelNames, migratable) < 0)
459f93
         return NULL;
459f93
 
459f93
-    if (STREQ_NULLABLE(cpu->model, modelName))
459f93
+    if (namesLen == 1 && STREQ(cpu->model, modelNames[0]))
459f93
         cpu->fallback = VIR_CPU_FALLBACK_FORBID;
459f93
 
459f93
     if (!outputVendor)
459f93
diff --git a/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml
459f93
index 775a27de2e..f5846b1619 100644
459f93
--- a/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml
459f93
+++ b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-migratable.xml
459f93
@@ -1,10 +1,14 @@
459f93
 <cpu mode='custom' match='exact'>
459f93
-  <model fallback='allow'>SandyBridge</model>
459f93
+  <model fallback='allow'>Westmere</model>
459f93
   <vendor>Intel</vendor>
459f93
   <feature policy='require' name='vme'/>
459f93
   <feature policy='require' name='ss'/>
459f93
+  <feature policy='require' name='pclmuldq'/>
459f93
   <feature policy='require' name='pcid'/>
459f93
+  <feature policy='require' name='x2apic'/>
459f93
+  <feature policy='require' name='tsc-deadline'/>
459f93
+  <feature policy='require' name='xsave'/>
459f93
   <feature policy='require' name='osxsave'/>
459f93
+  <feature policy='require' name='avx'/>
459f93
   <feature policy='require' name='hypervisor'/>
459f93
-  <feature policy='disable' name='rdtscp'/>
459f93
 </cpu>
459f93
diff --git a/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml
459f93
index cafca97d62..166833276c 100644
459f93
--- a/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml
459f93
+++ b/tests/cputestdata/x86_64-baseline-Westmere+Nehalem-result.xml
459f93
@@ -1,11 +1,15 @@
459f93
 <cpu mode='custom' match='exact'>
459f93
-  <model fallback='allow'>SandyBridge</model>
459f93
+  <model fallback='allow'>Westmere</model>
459f93
   <vendor>Intel</vendor>
459f93
   <feature policy='require' name='vme'/>
459f93
   <feature policy='require' name='ss'/>
459f93
+  <feature policy='require' name='pclmuldq'/>
459f93
   <feature policy='require' name='pcid'/>
459f93
+  <feature policy='require' name='x2apic'/>
459f93
+  <feature policy='require' name='tsc-deadline'/>
459f93
+  <feature policy='require' name='xsave'/>
459f93
   <feature policy='require' name='osxsave'/>
459f93
+  <feature policy='require' name='avx'/>
459f93
   <feature policy='require' name='hypervisor'/>
459f93
   <feature policy='require' name='invtsc'/>
459f93
-  <feature policy='disable' name='rdtscp'/>
459f93
 </cpu>
459f93
diff --git a/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml
459f93
index 46c32c996f..ecac749b97 100644
459f93
--- a/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml
459f93
+++ b/tests/cputestdata/x86_64-cpuid-baseline-Cooperlake+Cascadelake.xml
459f93
@@ -1,17 +1,22 @@
459f93
 <cpu mode='custom' match='exact'>
459f93
-  <model fallback='allow'>Cooperlake</model>
459f93
+  <model fallback='allow'>Cascadelake-Server</model>
459f93
   <vendor>Intel</vendor>
459f93
   <feature policy='require' name='ss'/>
459f93
   <feature policy='require' name='vmx'/>
459f93
   <feature policy='require' name='hypervisor'/>
459f93
   <feature policy='require' name='tsc_adjust'/>
459f93
-  <feature policy='require' name='mpx'/>
459f93
   <feature policy='require' name='umip'/>
459f93
+  <feature policy='require' name='pku'/>
459f93
   <feature policy='require' name='md-clear'/>
459f93
+  <feature policy='require' name='stibp'/>
459f93
+  <feature policy='require' name='arch-capabilities'/>
459f93
   <feature policy='require' name='xsaves'/>
459f93
   <feature policy='require' name='ibpb'/>
459f93
   <feature policy='require' name='amd-ssbd'/>
459f93
+  <feature policy='require' name='rdctl-no'/>
459f93
+  <feature policy='require' name='ibrs-all'/>
459f93
+  <feature policy='require' name='skip-l1dfl-vmentry'/>
459f93
+  <feature policy='require' name='mds-no'/>
459f93
+  <feature policy='require' name='pschange-mc-no'/>
459f93
   <feature policy='require' name='tsx-ctrl'/>
459f93
-  <feature policy='disable' name='avx512-bf16'/>
459f93
-  <feature policy='disable' name='taa-no'/>
459f93
 </cpu>
459f93
-- 
459f93
2.35.1
459f93