mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
qemu: Store host-model CPU in qemu capabilities
Host capabilities provide libvirt's view of the host CPU, but for a useful support for host-model CPUs we really need a hypervisor's view of the CPU. And since the view can be differ with emulator, qemu capabilities is the best place to store the host CPU model. This patch just copies the CPU model from host capabilities, but this will change in the future. Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
8fc6e7d824
commit
68c7011856
@ -385,6 +385,12 @@ struct _virQEMUCaps {
|
||||
|
||||
size_t ngicCapabilities;
|
||||
virGICCapability *gicCapabilities;
|
||||
|
||||
/* Anything below is not stored in the cache since the values are
|
||||
* re-computed from the other fields or external data sources every
|
||||
* time we probe QEMU or load the results from the cache.
|
||||
*/
|
||||
virCPUDefPtr hostCPUModel;
|
||||
};
|
||||
|
||||
struct virQEMUCapsSearchData {
|
||||
@ -2113,6 +2119,10 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (qemuCaps->hostCPUModel &&
|
||||
!(ret->hostCPUModel = virCPUDefCopy(qemuCaps->hostCPUModel)))
|
||||
goto error;
|
||||
|
||||
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
|
||||
goto error;
|
||||
ret->nmachineTypes = qemuCaps->nmachineTypes;
|
||||
@ -2157,6 +2167,8 @@ void virQEMUCapsDispose(void *obj)
|
||||
VIR_FREE(qemuCaps->binary);
|
||||
|
||||
VIR_FREE(qemuCaps->gicCapabilities);
|
||||
|
||||
virCPUDefFree(qemuCaps->hostCPUModel);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2902,6 +2914,38 @@ int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
||||
virCapsHostPtr host)
|
||||
{
|
||||
virCPUDefPtr cpu = NULL;
|
||||
|
||||
if (!virQEMUCapsGuestIsNative(host->arch, qemuCaps->arch))
|
||||
goto error;
|
||||
|
||||
if (host->cpu && host->cpu->model) {
|
||||
if (VIR_ALLOC(cpu) < 0)
|
||||
goto error;
|
||||
|
||||
cpu->sockets = cpu->cores = cpu->threads = 0;
|
||||
cpu->type = VIR_CPU_TYPE_GUEST;
|
||||
cpu->mode = VIR_CPU_MODE_CUSTOM;
|
||||
cpu->match = VIR_CPU_MATCH_EXACT;
|
||||
|
||||
if (virCPUDefCopyModel(cpu, host->cpu, true) < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
qemuCaps->hostCPUModel = cpu;
|
||||
return;
|
||||
|
||||
error:
|
||||
virCPUDefFree(cpu);
|
||||
qemuCaps->hostCPUModel = NULL;
|
||||
virResetLastError();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parsing a doc that looks like
|
||||
*
|
||||
@ -2920,8 +2964,11 @@ int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
|
||||
* </qemuCaps>
|
||||
*/
|
||||
int
|
||||
virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename,
|
||||
time_t *qemuctime, time_t *selfctime,
|
||||
virQEMUCapsLoadCache(virCapsPtr caps,
|
||||
virQEMUCapsPtr qemuCaps,
|
||||
const char *filename,
|
||||
time_t *qemuctime,
|
||||
time_t *selfctime,
|
||||
unsigned long *selfvers)
|
||||
{
|
||||
xmlDocPtr doc = NULL;
|
||||
@ -3154,6 +3201,8 @@ virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename,
|
||||
}
|
||||
VIR_FREE(nodes);
|
||||
|
||||
virQEMUCapsInitHostCPUModel(qemuCaps, &caps->host);
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_FREE(str);
|
||||
@ -3344,7 +3393,9 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
|
||||
|
||||
|
||||
static int
|
||||
virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, const char *cacheDir)
|
||||
virQEMUCapsInitCached(virCapsPtr caps,
|
||||
virQEMUCapsPtr qemuCaps,
|
||||
const char *cacheDir)
|
||||
{
|
||||
char *capsdir = NULL;
|
||||
char *capsfile = NULL;
|
||||
@ -3386,8 +3437,8 @@ virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, const char *cacheDir)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virQEMUCapsLoadCache(qemuCaps, capsfile, &qemuctime, &selfctime,
|
||||
&selfvers) < 0) {
|
||||
if (virQEMUCapsLoadCache(caps, qemuCaps, capsfile,
|
||||
&qemuctime, &selfctime, &selfvers) < 0) {
|
||||
VIR_WARN("Failed to load cached caps from '%s' for '%s': %s",
|
||||
capsfile, qemuCaps->binary, virGetLastErrorMessage());
|
||||
virResetLastError();
|
||||
@ -3871,7 +3922,7 @@ virQEMUCapsLogProbeFailure(const char *binary)
|
||||
|
||||
|
||||
virQEMUCapsPtr
|
||||
virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
|
||||
virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
|
||||
const char *binary,
|
||||
const char *libDir,
|
||||
const char *cacheDir,
|
||||
@ -3911,7 +3962,7 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
|
||||
|
||||
if (!cacheDir)
|
||||
rv = 0;
|
||||
else if ((rv = virQEMUCapsInitCached(qemuCaps, cacheDir)) < 0)
|
||||
else if ((rv = virQEMUCapsInitCached(caps, qemuCaps, cacheDir)) < 0)
|
||||
goto error;
|
||||
|
||||
if (rv == 0) {
|
||||
@ -3937,16 +3988,18 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
|
||||
if (cacheDir &&
|
||||
virQEMUCapsRememberCached(qemuCaps, cacheDir) < 0)
|
||||
goto error;
|
||||
|
||||
virQEMUCapsInitHostCPUModel(qemuCaps, &caps->host);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(qmperr);
|
||||
return qemuCaps;
|
||||
|
||||
error:
|
||||
VIR_FREE(qmperr);
|
||||
virObjectUnref(qemuCaps);
|
||||
qemuCaps = NULL;
|
||||
return NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
static virQEMUCapsPtr
|
||||
|
@ -48,7 +48,8 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
|
||||
gid_t runGid,
|
||||
bool qmpOnly);
|
||||
|
||||
int virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps,
|
||||
int virQEMUCapsLoadCache(virCapsPtr caps,
|
||||
virQEMUCapsPtr qemuCaps,
|
||||
const char *filename,
|
||||
time_t *qemuctime,
|
||||
time_t *selfctime,
|
||||
@ -60,4 +61,8 @@ char *virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps,
|
||||
void
|
||||
virQEMUCapsSetArch(virQEMUCapsPtr qemuCaps,
|
||||
virArch arch);
|
||||
|
||||
void
|
||||
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
||||
virCapsHostPtr host);
|
||||
#endif
|
||||
|
@ -173,9 +173,13 @@ fillQemuCaps(virDomainCapsPtr domCaps,
|
||||
virQEMUCapsPtr qemuCaps = NULL;
|
||||
virDomainCapsLoaderPtr loader = &domCaps->os.loader;
|
||||
|
||||
if (!(caps = virCapabilitiesNew(domCaps->arch, false, false)) ||
|
||||
fakeHostCPU(caps, domCaps->arch) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virAsprintf(&path, "%s/qemucapabilitiesdata/%s.%s.xml",
|
||||
abs_srcdir, name, arch) < 0 ||
|
||||
!(qemuCaps = qemuTestParseCapabilities(path)))
|
||||
!(qemuCaps = qemuTestParseCapabilities(caps, path)))
|
||||
goto cleanup;
|
||||
|
||||
if (machine &&
|
||||
@ -188,10 +192,6 @@ fillQemuCaps(virDomainCapsPtr domCaps,
|
||||
virQEMUCapsGetDefaultMachine(qemuCaps)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(caps = virCapabilitiesNew(domCaps->arch, false, false)) ||
|
||||
fakeHostCPU(caps, domCaps->arch) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
|
||||
cfg->firmwares,
|
||||
cfg->nfirmwares) < 0)
|
||||
|
@ -97,7 +97,7 @@ testQemuCapsCopy(const void *opaque)
|
||||
false, false)))
|
||||
goto cleanup;
|
||||
|
||||
if (!(orig = qemuTestParseCapabilities(capsFile)))
|
||||
if (!(orig = qemuTestParseCapabilities(caps, capsFile)))
|
||||
goto cleanup;
|
||||
|
||||
if (!(copy = virQEMUCapsNewCopy(orig)))
|
||||
|
@ -347,7 +347,8 @@ testInitQEMUCaps(struct testInfo *info,
|
||||
|
||||
static int
|
||||
testUpdateQEMUCaps(const struct testInfo *info,
|
||||
virDomainObjPtr vm)
|
||||
virDomainObjPtr vm,
|
||||
virCapsPtr caps)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
@ -356,6 +357,8 @@ testUpdateQEMUCaps(const struct testInfo *info,
|
||||
if (testAddCPUModels(info->qemuCaps, info->skipLegacyCPUs) < 0)
|
||||
goto cleanup;
|
||||
|
||||
virQEMUCapsInitHostCPUModel(info->qemuCaps, &caps->host);
|
||||
|
||||
virQEMUCapsFilterByMachineType(info->qemuCaps, vm->def->os.machine);
|
||||
|
||||
if (ARCH_IS_X86(vm->def->os.arch))
|
||||
@ -448,7 +451,7 @@ testCompareXMLToArgv(const void *data)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (testUpdateQEMUCaps(info, vm) < 0)
|
||||
if (testUpdateQEMUCaps(info, vm, driver.caps) < 0)
|
||||
goto cleanup;
|
||||
|
||||
log = virTestLogContentAndReset();
|
||||
|
@ -491,7 +491,8 @@ qemuTestSetHostCPU(virCapsPtr caps,
|
||||
|
||||
|
||||
virQEMUCapsPtr
|
||||
qemuTestParseCapabilities(const char *capsFile)
|
||||
qemuTestParseCapabilities(virCapsPtr caps,
|
||||
const char *capsFile)
|
||||
{
|
||||
virQEMUCapsPtr qemuCaps = NULL;
|
||||
time_t qemuctime;
|
||||
@ -499,7 +500,7 @@ qemuTestParseCapabilities(const char *capsFile)
|
||||
unsigned long version;
|
||||
|
||||
if (!(qemuCaps = virQEMUCapsNew()) ||
|
||||
virQEMUCapsLoadCache(qemuCaps, capsFile,
|
||||
virQEMUCapsLoadCache(caps, qemuCaps, capsFile,
|
||||
&qemuctime, &selfctime, &version) < 0)
|
||||
goto error;
|
||||
|
||||
|
@ -15,7 +15,8 @@ enum {
|
||||
virCapsPtr testQemuCapsInit(void);
|
||||
virDomainXMLOptionPtr testQemuXMLConfInit(void);
|
||||
|
||||
virQEMUCapsPtr qemuTestParseCapabilities(const char *capsFile);
|
||||
virQEMUCapsPtr qemuTestParseCapabilities(virCapsPtr caps,
|
||||
const char *capsFile);
|
||||
|
||||
extern virCPUDefPtr cpuDefault;
|
||||
extern virCPUDefPtr cpuHaswell;
|
||||
|
Loading…
Reference in New Issue
Block a user