From: "Collin L. Walling" <walling@xxxxxxxxxxxxxxxxxx> When qmp query-cpu-model-expansion is available probe Qemu for its view of the host model. In kvm environments this can provide a more complete view of the host model because features supported by Qemu and Kvm can be considered. Signed-off-by: Collin L. Walling <walling@xxxxxxxxxxxxxxxxxx> Signed-off-by: Jason J. Herne <jjherne@xxxxxxxxxxxxxxxxxx> --- src/qemu/qemu_capabilities.c | 88 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 7a8202a..4a6ae07 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -389,6 +389,8 @@ struct _virQEMUCaps { size_t ngicCapabilities; virGICCapability *gicCapabilities; + virCPUDefPtr hostCPUModelFromQemu; + /* 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. @@ -2118,6 +2120,10 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps) !(ret->hostCPUModel = virCPUDefCopy(qemuCaps->hostCPUModel))) goto error; + if (qemuCaps->hostCPUModelFromQemu && + !(ret->hostCPUModelFromQemu = virCPUDefCopy(qemuCaps->hostCPUModelFromQemu))) + goto error; + if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0) goto error; ret->nmachineTypes = qemuCaps->nmachineTypes; @@ -2728,6 +2734,51 @@ virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps, return ret; } +static int +virQEMUCapsProbeQMPCPUModelExpansion(virQEMUCapsPtr qemuCaps, + qemuMonitorPtr mon) +{ + qemuMonitorCPUModelInfoPtr model_info; + virCPUDefPtr hostcpumodel; + int nfeatures; + int ret = -1; + size_t i; + + if (qemuMonitorGetCPUModelExpansion(mon, "static", "host", &model_info) < 0) + goto cleanup; + + if (model_info == NULL) { + ret = 0; + goto cleanup; + } + + if (VIR_ALLOC(hostcpumodel) < 0) + goto cleanup; + + if (VIR_STRDUP(hostcpumodel->model, model_info->name) < 0) + goto cleanup; + + nfeatures = hostcpumodel->nfeatures = model_info->nprops; + + if (VIR_ALLOC_N(hostcpumodel->features, nfeatures) < 0) + goto cleanup; + + for (i = 0; i < nfeatures; i++) { + if (VIR_STRDUP(hostcpumodel->features[i].name, model_info->props[i].name) < 0) + goto cleanup; + + hostcpumodel->features[i].policy = -1; + } + + hostcpumodel->arch = qemuCaps->arch; + qemuCaps->hostCPUModelFromQemu = virCPUDefCopy(hostcpumodel); + ret = 0; + + cleanup: + virCPUDefFree(hostcpumodel); + return ret; +} + struct tpmTypeToCaps { int type; virQEMUCapsFlags caps; @@ -2958,6 +3009,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps, virCapsPtr caps) { virCPUDefPtr cpu = NULL; + virCPUDefPtr src = NULL; if (!caps) return; @@ -2974,7 +3026,10 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps, cpu->mode = VIR_CPU_MODE_CUSTOM; cpu->match = VIR_CPU_MATCH_EXACT; - if (virCPUDefCopyModelFilter(cpu, caps->host.cpu, true, + if (!(src = qemuCaps->hostCPUModelFromQemu)) + src = caps->host.cpu; + + if (virCPUDefCopyModelFilter(cpu, src, true, virQEMUCapsCPUFilterFeatures, NULL) < 0) goto error; } @@ -3118,6 +3173,21 @@ virQEMUCapsLoadCache(virCapsPtr caps, } VIR_FREE(str); + xmlNodePtr node; + if ((node = virXPathNode("./host/cpu[1]", ctxt))) { + xmlNodePtr oldNode = ctxt->node; + ctxt->node = node; + if (!(qemuCaps->hostCPUModelFromQemu = virCPUDefParseXML(node, + ctxt, + VIR_CPU_TYPE_HOST))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing host cpu data in QEMU capabilities cache")); + goto cleanup; + } + ctxt->node = oldNode; + node = NULL; + } + if ((n = virXPathNodeSet("./cpu", ctxt, &nodes)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to parse qemu capabilities cpus")); @@ -3298,6 +3368,20 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps, virBufferAsprintf(&buf, "<arch>%s</arch>\n", virArchToString(qemuCaps->arch)); + if (qemuCaps->hostCPUModelFromQemu) { + virBufferAddLit(&buf, "<host>\n"); + virBufferAdjustIndent(&buf, 2); + virBufferAddLit(&buf, "<cpu>\n"); + virBufferAdjustIndent(&buf, 2); + virBufferEscapeString(&buf, "<arch>%s</arch>\n", + virArchToString(qemuCaps->hostCPUModelFromQemu->arch)); + virCPUDefFormatBuf(&buf, qemuCaps->hostCPUModelFromQemu, true); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</cpu>\n"); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</host>\n"); + } + if (qemuCaps->cpuDefinitions) { for (i = 0; i < qemuCaps->cpuDefinitions->nmodels; i++) { virDomainCapsCPUModelPtr cpu = qemuCaps->cpuDefinitions->models + i; @@ -3790,6 +3874,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, goto cleanup; if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon) < 0) goto cleanup; + if (virQEMUCapsProbeQMPCPUModelExpansion(qemuCaps, mon) < 0) + goto cleanup; if (virQEMUCapsProbeQMPKVMState(qemuCaps, mon) < 0) goto cleanup; if (virQEMUCapsProbeQMPTPM(qemuCaps, mon) < 0) -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list