This function is hooked into the virsh hypervisor-cpu-models command. The CPU models are read directly from the QEMU capabilities file, which contains a list of all models queried from the hypervisor. Signed-off-by: Collin Walling <walling@xxxxxxxxxxxxx> Reviewed-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxx> --- src/qemu/qemu_driver.c | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 09ae893daf..e101da4d21 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12400,6 +12400,67 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn, } +static char * +qemuConnectGetHypervisorCPUModelNames(virConnectPtr conn, + const char *emulator, + const char *archStr, + const char *machine, + const char *virttypeStr, + unsigned int flags) +{ + virQEMUDriver *driver = conn->privateData; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + g_autoptr(virDomainCapsCPUModels) cpuModels = NULL; + g_autoptr(virQEMUCaps) qemuCaps = NULL; + char *modelsstr = g_strdup(""); + virDomainVirtType virttype; + virArch arch; + size_t i; + + virCheckFlags(0, NULL); + + if (virConnectGetHypervisorCPUModelNamesEnsureACL(conn) < 0) + return NULL; + + qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache, + emulator, + archStr, + virttypeStr, + machine, + &arch, &virttype, NULL); + if (!qemuCaps) + return NULL; + + if (!(cpuModels = virQEMUCapsGetCPUModels(qemuCaps, virttype, NULL, NULL)) || + cpuModels->nmodels == 0) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("QEMU '%s' does not support any CPU models for " + "virttype '%s'"), + virQEMUCapsGetBinary(qemuCaps), + virDomainVirtTypeToString(virttype)); + return NULL; + } + + for (i = 0; i < cpuModels->nmodels; i++) { + const char *name = cpuModels->models[i].name; + char *oldstr = modelsstr; + /* + * These models are not architecture-specific, but rather + * generic QEMU models, so let's filter them out + */ + if (STREQ(name, "host") || + STREQ(name, "qemu") || + STREQ(name, "max")) + continue; + + modelsstr = g_strdup_printf("%s\n%s", name, modelsstr); + g_free(oldstr); + } + + return modelsstr; +} + + static int qemuDomainGetJobInfoMigrationStats(virDomainObj *vm, virDomainJobData *jobData) @@ -20814,6 +20875,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainSetLifecycleAction = qemuDomainSetLifecycleAction, /* 3.9.0 */ .connectCompareHypervisorCPU = qemuConnectCompareHypervisorCPU, /* 4.4.0 */ .connectBaselineHypervisorCPU = qemuConnectBaselineHypervisorCPU, /* 4.4.0 */ + .connectGetHypervisorCPUModelNames = qemuConnectGetHypervisorCPUModelNames, /* 9.2.0 */ .nodeGetSEVInfo = qemuNodeGetSEVInfo, /* 4.5.0 */ .domainGetLaunchSecurityInfo = qemuDomainGetLaunchSecurityInfo, /* 4.5.0 */ .domainCheckpointCreateXML = qemuDomainCheckpointCreateXML, /* 5.6.0 */ -- 2.39.0