[libvirt] [PATCH 4/7] cpu: Add list of allowed CPU models to virCPUGetHost

Jiri Denemark jdenemar at redhat.com
Wed Mar 8 13:46:25 UTC 2017


When creating host CPU definition usable with a given emulator, the CPU
should not be defined using an unsupported CPU model. The new @models
and @nmodels parameters can be used to limit CPU models which can be
used in the result.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/bhyve/bhyve_capabilities.c |  3 ++-
 src/cpu/cpu.c                  | 19 +++++++++++++++----
 src/cpu/cpu.h                  |  8 ++++++--
 src/cpu/cpu_ppc64.c            |  6 ++++--
 src/cpu/cpu_x86.c              |  6 ++++--
 src/qemu/qemu_capabilities.c   |  3 ++-
 src/vmware/vmware_conf.c       |  3 ++-
 src/vz/vz_driver.c             |  2 +-
 8 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index 33e670c5c..60db0b791 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -47,7 +47,8 @@ virBhyveCapsInitCPU(virCapsPtr caps,
     if (nodeGetInfo(&nodeinfo))
         return -1;
 
-    if (!(caps->host.cpu = virCPUGetHost(arch, VIR_CPU_TYPE_HOST, &nodeinfo)))
+    if (!(caps->host.cpu = virCPUGetHost(arch, VIR_CPU_TYPE_HOST,
+                                         &nodeinfo, NULL, 0)))
         return -1;
 
     return 0;
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 110bb240c..5b1940b47 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -362,6 +362,8 @@ virCPUDataFree(virCPUDataPtr data)
  * @arch: CPU architecture
  * @type: requested type of the CPU
  * @nodeInfo: simplified CPU topology (optional)
+ * @models: list of CPU models that can be considered for host CPU
+ * @nmodels: number of CPU models in @models
  *
  * Create CPU definition describing the host's CPU.
  *
@@ -378,18 +380,26 @@ virCPUDataFree(virCPUDataPtr data)
  * host CPU model. In other words, a CPU definition containing just the
  * topology is a successful result even if detecting the host CPU model fails.
  *
+ * It possible to limit the CPU model which may appear in the created CPU
+ * definition by passing non-NULL @models list. This is useful when requesting
+ * a CPU model usable on a specific hypervisor. If @models is NULL, any CPU
+ * model known to libvirt may appear in the result.
+ *
  * Returns host CPU definition or NULL on error.
  */
 virCPUDefPtr
 virCPUGetHost(virArch arch,
               virCPUType type,
-              virNodeInfoPtr nodeInfo)
+              virNodeInfoPtr nodeInfo,
+              const char **models,
+              unsigned int nmodels)
 {
     struct cpuArchDriver *driver;
     virCPUDefPtr cpu = NULL;
 
-    VIR_DEBUG("arch=%s, type=%s, nodeInfo=%p",
-              virArchToString(arch), virCPUTypeToString(type), nodeInfo);
+    VIR_DEBUG("arch=%s, type=%s, nodeInfo=%p, models=%p, nmodels=%u",
+              virArchToString(arch), virCPUTypeToString(type), nodeInfo,
+              models, nmodels);
 
     if (!(driver = cpuGetSubDriver(arch)))
         return NULL;
@@ -431,7 +441,8 @@ virCPUGetHost(virArch arch,
      * filled in.
      */
     if (driver->getHost) {
-        if (driver->getHost(cpu) < 0 && !nodeInfo)
+        if (driver->getHost(cpu, models, nmodels) < 0 &&
+            !nodeInfo)
             goto error;
     } else if (nodeInfo) {
         VIR_DEBUG("cannot detect host CPU model for %s architecture",
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index e5eca08c3..c329eb134 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -71,7 +71,9 @@ typedef void
 (*cpuArchDataFree)  (virCPUDataPtr data);
 
 typedef int
-(*virCPUArchGetHost)(virCPUDefPtr cpu);
+(*virCPUArchGetHost)(virCPUDefPtr cpu,
+                     const char **models,
+                     unsigned int nmodels);
 
 typedef virCPUDefPtr
 (*cpuArchBaseline)  (virCPUDefPtr *cpus,
@@ -171,7 +173,9 @@ virCPUDataFree(virCPUDataPtr data);
 virCPUDefPtr
 virCPUGetHost(virArch arch,
               virCPUType type,
-              virNodeInfoPtr nodeInfo);
+              virNodeInfoPtr nodeInfo,
+              const char **models,
+              unsigned int nmodels);
 
 char *
 cpuBaselineXML(const char **xmlCPUs,
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
index bb715546b..6e16ffd13 100644
--- a/src/cpu/cpu_ppc64.c
+++ b/src/cpu/cpu_ppc64.c
@@ -716,7 +716,9 @@ virCPUppc64DataFree(virCPUDataPtr data)
 
 
 static int
-virCPUppc64GetHost(virCPUDefPtr cpu)
+virCPUppc64GetHost(virCPUDefPtr cpu,
+                   const char **models,
+                   unsigned int nmodels)
 {
     virCPUDataPtr cpuData = NULL;
     virCPUppc64Data *data;
@@ -738,7 +740,7 @@ virCPUppc64GetHost(virCPUDefPtr cpu)
 #endif
     data->pvr[0].mask = 0xfffffffful;
 
-    ret = ppc64DriverDecode(cpu, cpuData, NULL, 0, NULL, 0);
+    ret = ppc64DriverDecode(cpu, cpuData, models, nmodels, NULL, 0);
 
  cleanup:
     virCPUppc64DataFree(cpuData);
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index bddb169ba..6719acee2 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2438,7 +2438,9 @@ cpuidSet(uint32_t base, virCPUDataPtr data)
 
 
 static int
-virCPUx86GetHost(virCPUDefPtr cpu)
+virCPUx86GetHost(virCPUDefPtr cpu,
+                 const char **models,
+                 unsigned int nmodels)
 {
     virCPUDataPtr cpuData = NULL;
     int ret = -1;
@@ -2450,7 +2452,7 @@ virCPUx86GetHost(virCPUDefPtr cpu)
         cpuidSet(CPUX86_EXTENDED, cpuData) < 0)
         goto cleanup;
 
-    ret = x86DecodeCPUData(cpu, cpuData, NULL, 0, NULL, 0);
+    ret = x86DecodeCPUData(cpu, cpuData, models, nmodels, NULL, 0);
 
  cleanup:
     virCPUx86DataFree(cpuData);
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b39014224..319600c30 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1070,7 +1070,8 @@ virQEMUCapsInitCPU(virCapsPtr caps,
     if (nodeGetInfo(&nodeinfo))
         return -1;
 
-    if (!(caps->host.cpu = virCPUGetHost(arch, VIR_CPU_TYPE_HOST, &nodeinfo)))
+    if (!(caps->host.cpu = virCPUGetHost(arch, VIR_CPU_TYPE_HOST,
+                                         &nodeinfo, NULL, 0)))
         return -1;
 
     return 0;
diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c
index cb6d60724..659c4737a 100644
--- a/src/vmware/vmware_conf.c
+++ b/src/vmware/vmware_conf.c
@@ -82,7 +82,8 @@ vmwareCapsInit(void)
                                       NULL, NULL, 0, NULL) == NULL)
         goto error;
 
-    if (!(cpu = virCPUGetHost(caps->host.arch, VIR_CPU_TYPE_HOST, NULL)))
+    if (!(cpu = virCPUGetHost(caps->host.arch, VIR_CPU_TYPE_HOST,
+                              NULL, NULL, 0)))
         goto error;
 
     /* x86_64 guests are supported if
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 67ec2727b..b5d2964f3 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -130,7 +130,7 @@ vzBuildCapabilities(void)
         goto error;
 
     if (!(caps->host.cpu = virCPUGetHost(caps->host.arch, VIR_CPU_TYPE_HOST,
-                                         &nodeinfo)))
+                                         &nodeinfo, NULL, 0)))
         goto error;
 
     if (virCapabilitiesAddHostMigrateTransport(caps, "vzmigr") < 0)
-- 
2.12.0




More information about the libvir-list mailing list