[libvirt] [PATCH 19/22] cpu: Add optional list of allowed features to virCPUBaseline

Jiri Denemark jdenemar at redhat.com
Wed May 16 08:39:38 UTC 2018


When computing a baseline CPU for a specific hypervisor we have to make
sure to include only CPU features supported by the hypervisor. Otherwise
the computed CPU could not be used for starting a new domain.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/bhyve/bhyve_driver.c |  2 +-
 src/cpu/cpu.c            |  8 +++++---
 src/cpu/cpu.h            |  2 ++
 src/cpu/cpu_arm.c        |  1 +
 src/cpu/cpu_ppc64.c      |  1 +
 src/cpu/cpu_x86.c        | 18 ++++++++++++++++++
 src/libxl/libxl_driver.c |  2 +-
 src/qemu/qemu_driver.c   |  2 +-
 src/test/test_driver.c   |  2 +-
 src/vz/vz_driver.c       |  2 +-
 tests/cputest.c          |  2 +-
 11 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index 26047d31e2..97e8d4eb37 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -1398,7 +1398,7 @@ bhyveConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL,
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL,
                                !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index b6c1695f2a..cc93c49418 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -485,6 +485,7 @@ virCPUProbeHost(virArch arch)
  * @cpus: list of host CPU definitions
  * @ncpus: number of CPUs in @cpus
  * @models: list of CPU models that can be considered for the baseline CPU
+ * @features: optional NULL terminated list of allowed features
  * @migratable: requests non-migratable features to be removed from the result
  *
  * Computes the most feature-rich CPU which is compatible with all given
@@ -499,13 +500,14 @@ virCPUBaseline(virArch arch,
                virCPUDefPtr *cpus,
                unsigned int ncpus,
                virDomainCapsCPUModelsPtr models,
+               const char **features,
                bool migratable)
 {
     struct cpuArchDriver *driver;
     size_t i;
 
-    VIR_DEBUG("arch=%s, ncpus=%u, models=%p, migratable=%d",
-              virArchToString(arch), ncpus, models, migratable);
+    VIR_DEBUG("arch=%s, ncpus=%u, models=%p, features=%p, migratable=%d",
+              virArchToString(arch), ncpus, models, features, migratable);
     if (cpus) {
         for (i = 0; i < ncpus; i++)
             VIR_DEBUG("cpus[%zu]=%p", i, cpus[i]);
@@ -552,7 +554,7 @@ virCPUBaseline(virArch arch,
         return NULL;
     }
 
-    return driver->baseline(cpus, ncpus, models, migratable);
+    return driver->baseline(cpus, ncpus, models, features, migratable);
 }
 
 
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 8c45bf8b31..81119b6aeb 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -76,6 +76,7 @@ typedef virCPUDefPtr
 (*virCPUArchBaseline)(virCPUDefPtr *cpus,
                       unsigned int ncpus,
                       virDomainCapsCPUModelsPtr models,
+                      const char **features,
                       bool migratable);
 
 typedef int
@@ -198,6 +199,7 @@ virCPUBaseline(virArch arch,
                virCPUDefPtr *cpus,
                unsigned int ncpus,
                virDomainCapsCPUModelsPtr models,
+               const char **features,
                bool migratable);
 
 int
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index a9aa065f9f..cc7da44ac4 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -76,6 +76,7 @@ static virCPUDefPtr
 virCPUarmBaseline(virCPUDefPtr *cpus,
                   unsigned int ncpus ATTRIBUTE_UNUSED,
                   virDomainCapsCPUModelsPtr models ATTRIBUTE_UNUSED,
+                  const char **features ATTRIBUTE_UNUSED,
                   bool migratable ATTRIBUTE_UNUSED)
 {
     virCPUDefPtr cpu = NULL;
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
index c213245fc9..d562677fa3 100644
--- a/src/cpu/cpu_ppc64.c
+++ b/src/cpu/cpu_ppc64.c
@@ -770,6 +770,7 @@ static virCPUDefPtr
 virCPUppc64Baseline(virCPUDefPtr *cpus,
                     unsigned int ncpus,
                     virDomainCapsCPUModelsPtr models ATTRIBUTE_UNUSED,
+                    const char **features ATTRIBUTE_UNUSED,
                     bool migratable ATTRIBUTE_UNUSED)
 {
     struct ppc64_map *map;
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 6bef4089e9..809da94117 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2467,6 +2467,7 @@ static virCPUDefPtr
 virCPUx86Baseline(virCPUDefPtr *cpus,
                   unsigned int ncpus,
                   virDomainCapsCPUModelsPtr models,
+                  const char **features,
                   bool migratable)
 {
     virCPUx86MapPtr map = NULL;
@@ -2478,6 +2479,7 @@ virCPUx86Baseline(virCPUDefPtr *cpus,
     bool outputVendor = true;
     const char *modelName;
     bool matchingNames = true;
+    virCPUDataPtr featData = NULL;
 
     if (!(map = virCPUx86GetMap()))
         goto error;
@@ -2550,6 +2552,21 @@ virCPUx86Baseline(virCPUDefPtr *cpus,
         model = NULL;
     }
 
+    if (features) {
+        virCPUx86FeaturePtr feat;
+
+        if (!(featData = virCPUDataNew(archs[0])))
+            goto cleanup;
+
+        for (i = 0; features[i]; i++) {
+            if ((feat = x86FeatureFind(map, features[i])) &&
+                x86DataAdd(&featData->data.x86, &feat->data) < 0)
+                goto cleanup;
+        }
+
+        x86DataIntersect(&base_model->data, &featData->data.x86);
+    }
+
     if (x86DataIsEmpty(&base_model->data)) {
         virReportError(VIR_ERR_OPERATION_FAILED,
                        "%s", _("CPUs are incompatible"));
@@ -2571,6 +2588,7 @@ virCPUx86Baseline(virCPUDefPtr *cpus,
 
  cleanup:
     x86ModelFree(base_model);
+    virCPUx86DataFree(featData);
 
     return cpu;
 
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index a85ce84404..8c40661e5a 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -6349,7 +6349,7 @@ libxlConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL,
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL,
                                !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b95e1f5296..e036764f92 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13179,7 +13179,7 @@ qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(baseline = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL,
+    if (!(baseline = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL,
                                     !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 3b4acaf7fe..09f17bc8f9 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1536,7 +1536,7 @@ testConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, false)))
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL, false)))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 50cd0acfdf..c9520d4a58 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -934,7 +934,7 @@ vzConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, false)))
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL, false)))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/tests/cputest.c b/tests/cputest.c
index 9b84ffea86..baf2b3c648 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -321,7 +321,7 @@ cpuTestBaseline(const void *arg)
     if (!(cpus = cpuTestLoadMultiXML(data->arch, data->name, &ncpus)))
         goto cleanup;
 
-    baseline = virCPUBaseline(data->arch, cpus, ncpus, NULL,
+    baseline = virCPUBaseline(data->arch, cpus, ncpus, NULL, NULL,
                               !!(data->flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE));
 
     if (baseline &&
-- 
2.17.0




More information about the libvir-list mailing list