]> xenbits.xensource.com Git - libvirt.git/commitdiff
cpu: Add optional list of allowed features to virCPUBaseline
authorJiri Denemark <jdenemar@redhat.com>
Tue, 15 May 2018 09:57:35 +0000 (11:57 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Mon, 28 May 2018 13:59:11 +0000 (15:59 +0200)
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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Collin Walling <walling@linux.ibm.com>
src/bhyve/bhyve_driver.c
src/cpu/cpu.c
src/cpu/cpu.h
src/cpu/cpu_arm.c
src/cpu/cpu_ppc64.c
src/cpu/cpu_x86.c
src/libxl/libxl_driver.c
src/qemu/qemu_driver.c
src/test/test_driver.c
src/vz/vz_driver.c
tests/cputest.c

index 26047d31e294031fa4f424629459cedbd0b4909d..97e8d4eb3752041d1020ec89244ab1bfc7c4dc21 100644 (file)
@@ -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;
 
index b6c1695f2aec20317fcac3fb809000709b83428d..cc93c494180b6436776c29155abd38686b9f8c3f 100644 (file)
@@ -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);
 }
 
 
index 8c45bf8b3123af76531ab1a765c1e3c47561d49f..81119b6aeb13d8a4f205a132810882815bf2020b 100644 (file)
@@ -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
index a9aa065f9f50423b83013196026bf6226cce4f68..cc7da44ac4048ae418275443edb817a3a5fbc9b0 100644 (file)
@@ -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;
index c213245fc9fa3b4996bf22799e196d16044e5fbb..d562677fa389f451ca957923083cc0ccb514987b 100644 (file)
@@ -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;
index 6bef4089e914f13f4c05852318f9d33813af5a38..809da9411733eb45b0b7471b24489be404b67d0c 100644 (file)
@@ -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;
 
index a85ce84404c35d4755d13d07fa8fe58c44a3d5ae..8c40661e5a4a4bb29ca0a4d391e236e668e9c922 100644 (file)
@@ -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;
 
index 71a6ec95404f6388ff467d8c90df8dbb5d205416..f6346f54cdc4e3f5218027c8caec05b38f507803 100644 (file)
@@ -13315,7 +13315,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;
 
index 9456dfe38538a329def14197c64c4024482bcc88..a43b9781eb3b1d15fd2c54a63eac3b9fc3d42eec 100644 (file)
@@ -1541,7 +1541,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) &&
index 50cd0acfdfee0d56b71afea05cd1f9aad68f4a15..c9520d4a584bf2e05b98c506ae9b5cc8facbeb80 100644 (file)
@@ -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) &&
index 9b84ffea86f4f158040384379d5be3695d1c2f0c..baf2b3c648127348bb8bbec78a39487fcef26f64 100644 (file)
@@ -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 &&