mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
cpu: Replace cpuNodeData with virCPUGetHost
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@redhat.com>
This commit is contained in:
parent
5cbc247e0d
commit
23a3f5f50c
@ -43,41 +43,17 @@ VIR_LOG_INIT("bhyve.bhyve_capabilities");
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
virBhyveCapsInitCPU(virCapsPtr caps,
|
virBhyveCapsInitCPU(virCapsPtr caps,
|
||||||
virArch arch)
|
virArch arch)
|
||||||
{
|
{
|
||||||
virCPUDefPtr cpu = NULL;
|
|
||||||
virCPUDataPtr data = NULL;
|
|
||||||
virNodeInfo nodeinfo;
|
virNodeInfo nodeinfo;
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (VIR_ALLOC(cpu) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cpu->arch = arch;
|
|
||||||
|
|
||||||
if (nodeGetInfo(&nodeinfo))
|
if (nodeGetInfo(&nodeinfo))
|
||||||
goto error;
|
return -1;
|
||||||
|
|
||||||
cpu->type = VIR_CPU_TYPE_HOST;
|
if (!(caps->host.cpu = virCPUGetHost(arch, &nodeinfo)))
|
||||||
cpu->sockets = nodeinfo.sockets;
|
return -1;
|
||||||
cpu->cores = nodeinfo.cores;
|
|
||||||
cpu->threads = nodeinfo.threads;
|
|
||||||
caps->host.cpu = cpu;
|
|
||||||
|
|
||||||
if (!(data = cpuNodeData(arch)) ||
|
return 0;
|
||||||
cpuDecode(cpu, data, NULL, 0, NULL) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
virCPUDataFree(data);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
error:
|
|
||||||
virCPUDefFree(cpu);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virCapsPtr
|
virCapsPtr
|
||||||
|
@ -357,30 +357,66 @@ virCPUDataFree(virCPUDataPtr data)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpuNodeData:
|
* virCPUGetHost:
|
||||||
*
|
*
|
||||||
* @arch: CPU architecture
|
* @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
|
virCPUDefPtr
|
||||||
cpuNodeData(virArch arch)
|
virCPUGetHost(virArch arch,
|
||||||
|
virNodeInfoPtr nodeInfo)
|
||||||
{
|
{
|
||||||
struct cpuArchDriver *driver;
|
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;
|
return NULL;
|
||||||
|
|
||||||
if (driver->nodeData == NULL) {
|
if (VIR_ALLOC(cpu) < 0)
|
||||||
virReportError(VIR_ERR_NO_SUPPORT,
|
|
||||||
_("cannot get node CPU data for %s architecture"),
|
|
||||||
virArchToString(arch));
|
|
||||||
return NULL;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ typedef int
|
|||||||
typedef void
|
typedef void
|
||||||
(*cpuArchDataFree) (virCPUDataPtr data);
|
(*cpuArchDataFree) (virCPUDataPtr data);
|
||||||
|
|
||||||
typedef virCPUDataPtr
|
typedef int
|
||||||
(*cpuArchNodeData) (virArch arch);
|
(*virCPUArchGetHost)(virCPUDefPtr cpu);
|
||||||
|
|
||||||
typedef virCPUDefPtr
|
typedef virCPUDefPtr
|
||||||
(*cpuArchBaseline) (virCPUDefPtr *cpus,
|
(*cpuArchBaseline) (virCPUDefPtr *cpus,
|
||||||
@ -117,7 +117,7 @@ struct cpuArchDriver {
|
|||||||
cpuArchDecode decode;
|
cpuArchDecode decode;
|
||||||
cpuArchEncode encode;
|
cpuArchEncode encode;
|
||||||
cpuArchDataFree dataFree;
|
cpuArchDataFree dataFree;
|
||||||
cpuArchNodeData nodeData;
|
virCPUArchGetHost getHost;
|
||||||
cpuArchBaseline baseline;
|
cpuArchBaseline baseline;
|
||||||
virCPUArchUpdate update;
|
virCPUArchUpdate update;
|
||||||
virCPUArchCheckFeature checkFeature;
|
virCPUArchCheckFeature checkFeature;
|
||||||
@ -168,8 +168,9 @@ virCPUDataNew(virArch arch);
|
|||||||
void
|
void
|
||||||
virCPUDataFree(virCPUDataPtr data);
|
virCPUDataFree(virCPUDataPtr data);
|
||||||
|
|
||||||
virCPUDataPtr
|
virCPUDefPtr
|
||||||
cpuNodeData (virArch arch);
|
virCPUGetHost(virArch arch,
|
||||||
|
virNodeInfoPtr nodeInfo);
|
||||||
|
|
||||||
char *
|
char *
|
||||||
cpuBaselineXML(const char **xmlCPUs,
|
cpuBaselineXML(const char **xmlCPUs,
|
||||||
|
@ -111,7 +111,6 @@ struct cpuArchDriver cpuDriverArm = {
|
|||||||
.compare = virCPUarmCompare,
|
.compare = virCPUarmCompare,
|
||||||
.decode = NULL,
|
.decode = NULL,
|
||||||
.encode = NULL,
|
.encode = NULL,
|
||||||
.nodeData = NULL,
|
|
||||||
.baseline = armBaseline,
|
.baseline = armBaseline,
|
||||||
.update = virCPUarmUpdate,
|
.update = virCPUarmUpdate,
|
||||||
};
|
};
|
||||||
|
@ -714,19 +714,21 @@ virCPUppc64DataFree(virCPUDataPtr data)
|
|||||||
VIR_FREE(data);
|
VIR_FREE(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static virCPUDataPtr
|
|
||||||
ppc64DriverNodeData(virArch arch)
|
static int
|
||||||
|
virCPUppc64GetHost(virCPUDefPtr cpu)
|
||||||
{
|
{
|
||||||
virCPUDataPtr nodeData;
|
virCPUDataPtr cpuData = NULL;
|
||||||
virCPUppc64Data *data;
|
virCPUppc64Data *data;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
if (VIR_ALLOC(nodeData) < 0)
|
if (!(cpuData = virCPUDataNew(archs[0])))
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
data = &nodeData->data.ppc64;
|
data = &cpuData->data.ppc64;
|
||||||
|
|
||||||
if (VIR_ALLOC_N(data->pvr, 1) < 0)
|
if (VIR_ALLOC_N(data->pvr, 1) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
data->len = 1;
|
data->len = 1;
|
||||||
|
|
||||||
@ -736,13 +738,11 @@ ppc64DriverNodeData(virArch arch)
|
|||||||
#endif
|
#endif
|
||||||
data->pvr[0].mask = 0xfffffffful;
|
data->pvr[0].mask = 0xfffffffful;
|
||||||
|
|
||||||
nodeData->arch = arch;
|
ret = ppc64DriverDecode(cpu, cpuData, NULL, 0, NULL, 0);
|
||||||
|
|
||||||
return nodeData;
|
cleanup:
|
||||||
|
virCPUppc64DataFree(cpuData);
|
||||||
error:
|
return ret;
|
||||||
virCPUppc64DataFree(nodeData);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -902,7 +902,7 @@ struct cpuArchDriver cpuDriverPPC64 = {
|
|||||||
.decode = ppc64DriverDecode,
|
.decode = ppc64DriverDecode,
|
||||||
.encode = NULL,
|
.encode = NULL,
|
||||||
.dataFree = virCPUppc64DataFree,
|
.dataFree = virCPUppc64DataFree,
|
||||||
.nodeData = ppc64DriverNodeData,
|
.getHost = virCPUppc64GetHost,
|
||||||
.baseline = ppc64DriverBaseline,
|
.baseline = ppc64DriverBaseline,
|
||||||
.update = virCPUppc64Update,
|
.update = virCPUppc64Update,
|
||||||
.getModels = virCPUppc64DriverGetModels,
|
.getModels = virCPUppc64DriverGetModels,
|
||||||
|
@ -109,7 +109,6 @@ struct cpuArchDriver cpuDriverS390 = {
|
|||||||
.compare = virCPUs390Compare,
|
.compare = virCPUs390Compare,
|
||||||
.decode = NULL,
|
.decode = NULL,
|
||||||
.encode = NULL,
|
.encode = NULL,
|
||||||
.nodeData = NULL,
|
|
||||||
.baseline = NULL,
|
.baseline = NULL,
|
||||||
.update = virCPUs390Update,
|
.update = virCPUs390Update,
|
||||||
};
|
};
|
||||||
|
@ -2437,25 +2437,24 @@ cpuidSet(uint32_t base, virCPUDataPtr data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static virCPUDataPtr
|
static int
|
||||||
x86NodeData(virArch arch)
|
virCPUx86GetHost(virCPUDefPtr cpu)
|
||||||
{
|
{
|
||||||
virCPUDataPtr cpuData = NULL;
|
virCPUDataPtr cpuData = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
if (!(cpuData = virCPUDataNew(arch)))
|
if (!(cpuData = virCPUDataNew(archs[0])))
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
if (cpuidSet(CPUX86_BASIC, cpuData) < 0)
|
if (cpuidSet(CPUX86_BASIC, cpuData) < 0 ||
|
||||||
goto error;
|
cpuidSet(CPUX86_EXTENDED, cpuData) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (cpuidSet(CPUX86_EXTENDED, cpuData) < 0)
|
ret = x86DecodeCPUData(cpu, cpuData, NULL, 0, NULL, 0);
|
||||||
goto error;
|
|
||||||
|
|
||||||
return cpuData;
|
cleanup:
|
||||||
|
|
||||||
error:
|
|
||||||
virCPUx86DataFree(cpuData);
|
virCPUx86DataFree(cpuData);
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2849,9 +2848,7 @@ struct cpuArchDriver cpuDriverX86 = {
|
|||||||
.encode = x86Encode,
|
.encode = x86Encode,
|
||||||
.dataFree = virCPUx86DataFree,
|
.dataFree = virCPUx86DataFree,
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
.nodeData = x86NodeData,
|
.getHost = virCPUx86GetHost,
|
||||||
#else
|
|
||||||
.nodeData = NULL,
|
|
||||||
#endif
|
#endif
|
||||||
.baseline = x86Baseline,
|
.baseline = x86Baseline,
|
||||||
.update = virCPUx86Update,
|
.update = virCPUx86Update,
|
||||||
|
@ -996,7 +996,6 @@ cpuBaseline;
|
|||||||
cpuBaselineXML;
|
cpuBaselineXML;
|
||||||
cpuDecode;
|
cpuDecode;
|
||||||
cpuEncode;
|
cpuEncode;
|
||||||
cpuNodeData;
|
|
||||||
virCPUCheckFeature;
|
virCPUCheckFeature;
|
||||||
virCPUCompare;
|
virCPUCompare;
|
||||||
virCPUCompareXML;
|
virCPUCompareXML;
|
||||||
@ -1006,6 +1005,7 @@ virCPUDataFormat;
|
|||||||
virCPUDataFree;
|
virCPUDataFree;
|
||||||
virCPUDataNew;
|
virCPUDataNew;
|
||||||
virCPUDataParse;
|
virCPUDataParse;
|
||||||
|
virCPUGetHost;
|
||||||
virCPUGetModels;
|
virCPUGetModels;
|
||||||
virCPUTranslate;
|
virCPUTranslate;
|
||||||
virCPUUpdate;
|
virCPUUpdate;
|
||||||
|
@ -1065,39 +1065,15 @@ static int
|
|||||||
virQEMUCapsInitCPU(virCapsPtr caps,
|
virQEMUCapsInitCPU(virCapsPtr caps,
|
||||||
virArch arch)
|
virArch arch)
|
||||||
{
|
{
|
||||||
virCPUDefPtr cpu = NULL;
|
|
||||||
virCPUDataPtr data = NULL;
|
|
||||||
virNodeInfo nodeinfo;
|
virNodeInfo nodeinfo;
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (VIR_ALLOC(cpu) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cpu->arch = arch;
|
|
||||||
|
|
||||||
if (nodeGetInfo(&nodeinfo))
|
if (nodeGetInfo(&nodeinfo))
|
||||||
goto error;
|
return -1;
|
||||||
|
|
||||||
cpu->type = VIR_CPU_TYPE_HOST;
|
if (!(caps->host.cpu = virCPUGetHost(arch, &nodeinfo)))
|
||||||
cpu->sockets = nodeinfo.sockets;
|
return -1;
|
||||||
cpu->cores = nodeinfo.cores;
|
|
||||||
cpu->threads = nodeinfo.threads;
|
|
||||||
caps->host.cpu = cpu;
|
|
||||||
|
|
||||||
if (!(data = cpuNodeData(arch))
|
return 0;
|
||||||
|| cpuDecode(cpu, data, NULL, 0, NULL) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
virCPUDataFree(data);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
error:
|
|
||||||
virCPUDefFree(cpu);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,7 +62,6 @@ vmwareCapsInit(void)
|
|||||||
virCapsPtr caps = NULL;
|
virCapsPtr caps = NULL;
|
||||||
virCapsGuestPtr guest = NULL;
|
virCapsGuestPtr guest = NULL;
|
||||||
virCPUDefPtr cpu = NULL;
|
virCPUDefPtr cpu = NULL;
|
||||||
virCPUDataPtr data = NULL;
|
|
||||||
|
|
||||||
if ((caps = virCapabilitiesNew(virArchFromHost(),
|
if ((caps = virCapabilitiesNew(virArchFromHost(),
|
||||||
false, false)) == NULL)
|
false, false)) == NULL)
|
||||||
@ -83,26 +82,18 @@ vmwareCapsInit(void)
|
|||||||
NULL, NULL, 0, NULL) == NULL)
|
NULL, NULL, 0, NULL) == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (VIR_ALLOC(cpu) < 0)
|
if (!(cpu = virCPUGetHost(caps->host.arch, NULL)))
|
||||||
goto error;
|
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
|
/* x86_64 guests are supported if
|
||||||
* - Host arch is x86_64
|
* - Host arch is x86_64
|
||||||
* Or
|
* Or
|
||||||
* - Host CPU is x86_64 with virtualization extensions
|
* - Host CPU is x86_64 with virtualization extensions
|
||||||
*/
|
*/
|
||||||
if (caps->host.arch == VIR_ARCH_X86_64 ||
|
if (caps->host.arch == VIR_ARCH_X86_64 ||
|
||||||
(virCPUDataCheckFeature(data, "lm") &&
|
(virCPUCheckFeature(cpu->arch, cpu, "lm") &&
|
||||||
(virCPUDataCheckFeature(data, "vmx") ||
|
(virCPUCheckFeature(cpu->arch, cpu, "vmx") ||
|
||||||
virCPUDataCheckFeature(data, "svm")))) {
|
virCPUCheckFeature(cpu->arch, cpu, "svm")))) {
|
||||||
|
|
||||||
if ((guest = virCapabilitiesAddGuest(caps,
|
if ((guest = virCapabilitiesAddGuest(caps,
|
||||||
VIR_DOMAIN_OSTYPE_HVM,
|
VIR_DOMAIN_OSTYPE_HVM,
|
||||||
@ -118,8 +109,6 @@ vmwareCapsInit(void)
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virCPUDefFree(cpu);
|
virCPUDefFree(cpu);
|
||||||
virCPUDataFree(data);
|
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -99,8 +99,6 @@ static virCapsPtr
|
|||||||
vzBuildCapabilities(void)
|
vzBuildCapabilities(void)
|
||||||
{
|
{
|
||||||
virCapsPtr caps = NULL;
|
virCapsPtr caps = NULL;
|
||||||
virCPUDefPtr cpu = NULL;
|
|
||||||
virCPUDataPtr data = NULL;
|
|
||||||
virNodeInfo nodeinfo;
|
virNodeInfo nodeinfo;
|
||||||
virDomainOSType ostypes[] = {
|
virDomainOSType ostypes[] = {
|
||||||
VIR_DOMAIN_OSTYPE_HVM,
|
VIR_DOMAIN_OSTYPE_HVM,
|
||||||
@ -131,32 +129,17 @@ vzBuildCapabilities(void)
|
|||||||
if (nodeGetInfo(&nodeinfo))
|
if (nodeGetInfo(&nodeinfo))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (VIR_ALLOC(cpu) < 0)
|
if (!(caps->host.cpu = virCPUGetHost(caps->host.arch, &nodeinfo)))
|
||||||
goto error;
|
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)
|
if (virCapabilitiesAddHostMigrateTransport(caps, "vzmigr") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!(data = cpuNodeData(cpu->arch))
|
|
||||||
|| cpuDecode(cpu, data, NULL, 0, NULL) < 0) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
virCPUDataFree(data);
|
|
||||||
return caps;
|
return caps;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
virObjectUnref(caps);
|
virObjectUnref(caps);
|
||||||
goto cleanup;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vzDriverDispose(void * obj)
|
static void vzDriverDispose(void * obj)
|
||||||
|
Loading…
Reference in New Issue
Block a user