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(a)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