cpuNodeData has always been followed by cpuDecode as no hypervisor
driver is really interested in raw CPUID data for a host CPU. Let's
create a new CPU driver API which returns virCPUDefPtr directly.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/bhyve/bhyve_capabilities.c | 34 ++++---------------------
src/cpu/cpu.c | 58 ++++++++++++++++++++++++++++++++++--------
src/cpu/cpu.h | 11 ++++----
src/cpu/cpu_arm.c | 1 -
src/cpu/cpu_ppc64.c | 28 ++++++++++----------
src/cpu/cpu_s390.c | 1 -
src/cpu/cpu_x86.c | 27 +++++++++-----------
src/libvirt_private.syms | 2 +-
src/qemu/qemu_capabilities.c | 32 +++--------------------
src/vmware/vmware_conf.c | 19 +++-----------
src/vz/vz_driver.c | 21 ++-------------
11 files changed, 95 insertions(+), 139 deletions(-)
diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index 52d6ca782..c2c9303d7 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -40,41 +40,17 @@ VIR_LOG_INIT("bhyve.bhyve_capabilities");
static int
virBhyveCapsInitCPU(virCapsPtr caps,
- virArch arch)
+ virArch arch)
{
- virCPUDefPtr cpu = NULL;
- virCPUDataPtr data = NULL;
virNodeInfo nodeinfo;
- int ret = -1;
-
- if (VIR_ALLOC(cpu) < 0)
- goto error;
-
- cpu->arch = arch;
if (nodeGetInfo(&nodeinfo))
- goto error;
+ return -1;
- cpu->type = VIR_CPU_TYPE_HOST;
- cpu->sockets = nodeinfo.sockets;
- cpu->cores = nodeinfo.cores;
- cpu->threads = nodeinfo.threads;
- caps->host.cpu = cpu;
+ if (!(caps->host.cpu = virCPUGetHost(arch, &nodeinfo)))
+ return -1;
- if (!(data = cpuNodeData(arch)) ||
- cpuDecode(cpu, data, NULL, 0, NULL) < 0)
- goto cleanup;
-
- ret = 0;
-
- cleanup:
- virCPUDataFree(data);
-
- return ret;
-
- error:
- virCPUDefFree(cpu);
- goto cleanup;
+ return 0;
}
virCapsPtr
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 051a58040..c1666ed3b 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -357,30 +357,66 @@ virCPUDataFree(virCPUDataPtr data)
/**
- * cpuNodeData:
+ * virCPUGetHost:
*
* @arch: CPU architecture
+ * @nodeInfo: simplified CPU topology (optional)
*
- * Returns CPU data for host CPU or NULL on error.
+ * Create CPU definition describing the host's CPU. If @nodeInfo is not NULL,
+ * the CPU definition will have topology (sockets, cores, threads) filled in
+ * according to the content of @nodeInfo. The function fails only if @nodeInfo
+ * was not passed in and the assigned CPU driver was not able to detect the
+ * 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.
+ *
+ * Returns host CPU definition or NULL on error.
*/
-virCPUDataPtr
-cpuNodeData(virArch arch)
+virCPUDefPtr
+virCPUGetHost(virArch arch,
+ virNodeInfoPtr nodeInfo)
{
struct cpuArchDriver *driver;
+ virCPUDefPtr cpu = NULL;
- VIR_DEBUG("arch=%s", virArchToString(arch));
+ VIR_DEBUG("arch=%s, nodeInfo=%p",
+ virArchToString(arch), nodeInfo);
- if ((driver = cpuGetSubDriver(arch)) == NULL)
+ if (!(driver = cpuGetSubDriver(arch)))
return NULL;
- if (driver->nodeData == NULL) {
- virReportError(VIR_ERR_NO_SUPPORT,
- _("cannot get node CPU data for %s architecture"),
- virArchToString(arch));
+ if (VIR_ALLOC(cpu) < 0)
return NULL;
+
+ cpu->arch = arch;
+ cpu->type = VIR_CPU_TYPE_HOST;
+
+ if (nodeInfo) {
+ cpu->sockets = nodeInfo->sockets;
+ cpu->cores = nodeInfo->cores;
+ cpu->threads = nodeInfo->threads;
}
- return driver->nodeData(arch);
+ /* Try to get the host CPU model, but don't really fail if nodeInfo is
+ * filled in.
+ */
+ if (driver->getHost) {
+ if (driver->getHost(cpu) < 0 && !nodeInfo)
+ goto error;
+ } else if (nodeInfo) {
+ VIR_DEBUG("cannot detect host CPU model for %s architecture",
+ virArchToString(arch));
+ } else {
+ virReportError(VIR_ERR_NO_SUPPORT,
+ _("cannot detect host CPU model for %s architecture"),
+ virArchToString(arch));
+ goto error;
+ }
+
+ return cpu;
+
+ error:
+ virCPUDefFree(cpu);
+ return NULL;
}
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 0324284b9..cbbb45223 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -70,8 +70,8 @@ typedef int
typedef void
(*cpuArchDataFree) (virCPUDataPtr data);
-typedef virCPUDataPtr
-(*cpuArchNodeData) (virArch arch);
+typedef int
+(*virCPUArchGetHost)(virCPUDefPtr cpu);
typedef virCPUDefPtr
(*cpuArchBaseline) (virCPUDefPtr *cpus,
@@ -117,7 +117,7 @@ struct cpuArchDriver {
cpuArchDecode decode;
cpuArchEncode encode;
cpuArchDataFree dataFree;
- cpuArchNodeData nodeData;
+ virCPUArchGetHost getHost;
cpuArchBaseline baseline;
virCPUArchUpdate update;
virCPUArchCheckFeature checkFeature;
@@ -168,8 +168,9 @@ virCPUDataNew(virArch arch);
void
virCPUDataFree(virCPUDataPtr data);
-virCPUDataPtr
-cpuNodeData (virArch arch);
+virCPUDefPtr
+virCPUGetHost(virArch arch,
+ virNodeInfoPtr nodeInfo);
char *
cpuBaselineXML(const char **xmlCPUs,
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index 3a0ee2b14..a1aba2554 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -111,7 +111,6 @@ struct cpuArchDriver cpuDriverArm = {
.compare = virCPUarmCompare,
.decode = NULL,
.encode = NULL,
- .nodeData = NULL,
.baseline = armBaseline,
.update = virCPUarmUpdate,
};
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
index a7c8545db..bb715546b 100644
--- a/src/cpu/cpu_ppc64.c
+++ b/src/cpu/cpu_ppc64.c
@@ -714,19 +714,21 @@ virCPUppc64DataFree(virCPUDataPtr data)
VIR_FREE(data);
}
-static virCPUDataPtr
-ppc64DriverNodeData(virArch arch)
+
+static int
+virCPUppc64GetHost(virCPUDefPtr cpu)
{
- virCPUDataPtr nodeData;
+ virCPUDataPtr cpuData = NULL;
virCPUppc64Data *data;
+ int ret = -1;
- if (VIR_ALLOC(nodeData) < 0)
- goto error;
+ if (!(cpuData = virCPUDataNew(archs[0])))
+ goto cleanup;
- data = &nodeData->data.ppc64;
+ data = &cpuData->data.ppc64;
if (VIR_ALLOC_N(data->pvr, 1) < 0)
- goto error;
+ goto cleanup;
data->len = 1;
@@ -736,13 +738,11 @@ ppc64DriverNodeData(virArch arch)
#endif
data->pvr[0].mask = 0xfffffffful;
- nodeData->arch = arch;
+ ret = ppc64DriverDecode(cpu, cpuData, NULL, 0, NULL, 0);
- return nodeData;
-
- error:
- virCPUppc64DataFree(nodeData);
- return NULL;
+ cleanup:
+ virCPUppc64DataFree(cpuData);
+ return ret;
}
@@ -902,7 +902,7 @@ struct cpuArchDriver cpuDriverPPC64 = {
.decode = ppc64DriverDecode,
.encode = NULL,
.dataFree = virCPUppc64DataFree,
- .nodeData = ppc64DriverNodeData,
+ .getHost = virCPUppc64GetHost,
.baseline = ppc64DriverBaseline,
.update = virCPUppc64Update,
.getModels = virCPUppc64DriverGetModels,
diff --git a/src/cpu/cpu_s390.c b/src/cpu/cpu_s390.c
index 9503e8e2b..c08a24a53 100644
--- a/src/cpu/cpu_s390.c
+++ b/src/cpu/cpu_s390.c
@@ -109,7 +109,6 @@ struct cpuArchDriver cpuDriverS390 = {
.compare = virCPUs390Compare,
.decode = NULL,
.encode = NULL,
- .nodeData = NULL,
.baseline = NULL,
.update = virCPUs390Update,
};
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index bcf50cb9e..bddb169ba 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2437,25 +2437,24 @@ cpuidSet(uint32_t base, virCPUDataPtr data)
}
-static virCPUDataPtr
-x86NodeData(virArch arch)
+static int
+virCPUx86GetHost(virCPUDefPtr cpu)
{
virCPUDataPtr cpuData = NULL;
+ int ret = -1;
- if (!(cpuData = virCPUDataNew(arch)))
- goto error;
+ if (!(cpuData = virCPUDataNew(archs[0])))
+ goto cleanup;
- if (cpuidSet(CPUX86_BASIC, cpuData) < 0)
- goto error;
+ if (cpuidSet(CPUX86_BASIC, cpuData) < 0 ||
+ cpuidSet(CPUX86_EXTENDED, cpuData) < 0)
+ goto cleanup;
- if (cpuidSet(CPUX86_EXTENDED, cpuData) < 0)
- goto error;
+ ret = x86DecodeCPUData(cpu, cpuData, NULL, 0, NULL, 0);
- return cpuData;
-
- error:
+ cleanup:
virCPUx86DataFree(cpuData);
- return NULL;
+ return ret;
}
#endif
@@ -2849,9 +2848,7 @@ struct cpuArchDriver cpuDriverX86 = {
.encode = x86Encode,
.dataFree = virCPUx86DataFree,
#if defined(__i386__) || defined(__x86_64__)
- .nodeData = x86NodeData,
-#else
- .nodeData = NULL,
+ .getHost = virCPUx86GetHost,
#endif
.baseline = x86Baseline,
.update = virCPUx86Update,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6c89d44e2..4efea0098 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -996,7 +996,6 @@ cpuBaseline;
cpuBaselineXML;
cpuDecode;
cpuEncode;
-cpuNodeData;
virCPUCheckFeature;
virCPUCompare;
virCPUCompareXML;
@@ -1006,6 +1005,7 @@ virCPUDataFormat;
virCPUDataFree;
virCPUDataNew;
virCPUDataParse;
+virCPUGetHost;
virCPUGetModels;
virCPUTranslate;
virCPUUpdate;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 5a3b4ac50..b0a4861c3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1065,39 +1065,15 @@ static int
virQEMUCapsInitCPU(virCapsPtr caps,
virArch arch)
{
- virCPUDefPtr cpu = NULL;
- virCPUDataPtr data = NULL;
virNodeInfo nodeinfo;
- int ret = -1;
-
- if (VIR_ALLOC(cpu) < 0)
- goto error;
-
- cpu->arch = arch;
if (nodeGetInfo(&nodeinfo))
- goto error;
+ return -1;
- cpu->type = VIR_CPU_TYPE_HOST;
- cpu->sockets = nodeinfo.sockets;
- cpu->cores = nodeinfo.cores;
- cpu->threads = nodeinfo.threads;
- caps->host.cpu = cpu;
+ if (!(caps->host.cpu = virCPUGetHost(arch, &nodeinfo)))
+ return -1;
- if (!(data = cpuNodeData(arch))
- || cpuDecode(cpu, data, NULL, 0, NULL) < 0)
- goto cleanup;
-
- ret = 0;
-
- cleanup:
- virCPUDataFree(data);
-
- return ret;
-
- error:
- virCPUDefFree(cpu);
- goto cleanup;
+ return 0;
}
diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c
index 5b1b5f5fd..d1444e462 100644
--- a/src/vmware/vmware_conf.c
+++ b/src/vmware/vmware_conf.c
@@ -62,7 +62,6 @@ vmwareCapsInit(void)
virCapsPtr caps = NULL;
virCapsGuestPtr guest = NULL;
virCPUDefPtr cpu = NULL;
- virCPUDataPtr data = NULL;
if ((caps = virCapabilitiesNew(virArchFromHost(),
false, false)) == NULL)
@@ -83,26 +82,18 @@ vmwareCapsInit(void)
NULL, NULL, 0, NULL) == NULL)
goto error;
- if (VIR_ALLOC(cpu) < 0)
+ if (!(cpu = virCPUGetHost(caps->host.arch, NULL)))
goto error;
- cpu->arch = caps->host.arch;
- cpu->type = VIR_CPU_TYPE_HOST;
-
- if (!(data = cpuNodeData(cpu->arch))
- || cpuDecode(cpu, data, NULL, 0, NULL) < 0) {
- goto error;
- }
-
/* x86_64 guests are supported if
* - Host arch is x86_64
* Or
* - Host CPU is x86_64 with virtualization extensions
*/
if (caps->host.arch == VIR_ARCH_X86_64 ||
- (virCPUDataCheckFeature(data, "lm") &&
- (virCPUDataCheckFeature(data, "vmx") ||
- virCPUDataCheckFeature(data, "svm")))) {
+ (virCPUCheckFeature(cpu->arch, cpu, "lm") &&
+ (virCPUCheckFeature(cpu->arch, cpu, "vmx") ||
+ virCPUCheckFeature(cpu->arch, cpu, "svm")))) {
if ((guest = virCapabilitiesAddGuest(caps,
VIR_DOMAIN_OSTYPE_HVM,
@@ -118,8 +109,6 @@ vmwareCapsInit(void)
cleanup:
virCPUDefFree(cpu);
- virCPUDataFree(data);
-
return caps;
error:
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 1ca9fd726..f97a2045b 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -99,8 +99,6 @@ static virCapsPtr
vzBuildCapabilities(void)
{
virCapsPtr caps = NULL;
- virCPUDefPtr cpu = NULL;
- virCPUDataPtr data = NULL;
virNodeInfo nodeinfo;
virDomainOSType ostypes[] = {
VIR_DOMAIN_OSTYPE_HVM,
@@ -131,32 +129,17 @@ vzBuildCapabilities(void)
if (nodeGetInfo(&nodeinfo))
goto error;
- if (VIR_ALLOC(cpu) < 0)
+ if (!(caps->host.cpu = virCPUGetHost(caps->host.arch, &nodeinfo)))
goto error;
- cpu->arch = caps->host.arch;
- cpu->type = VIR_CPU_TYPE_HOST;
- cpu->sockets = nodeinfo.sockets;
- cpu->cores = nodeinfo.cores;
- cpu->threads = nodeinfo.threads;
-
- caps->host.cpu = cpu;
-
if (virCapabilitiesAddHostMigrateTransport(caps, "vzmigr") < 0)
goto error;
- if (!(data = cpuNodeData(cpu->arch))
- || cpuDecode(cpu, data, NULL, 0, NULL) < 0) {
- goto cleanup;
- }
-
- cleanup:
- virCPUDataFree(data);
return caps;
error:
virObjectUnref(caps);
- goto cleanup;
+ return NULL;
}
static void vzDriverDispose(void * obj)
--
2.12.0