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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list