From: Sandesh Patel <sandesh.patel@nutanix.com> Persist the list of ARM CPU properties and their host-supported values that was probed from QEMU into the on-disk QEMU capabilities cache, so that subsequent libvirtd starts do not have to re-issue the QMP query. Signed-off-by: Sandesh Patel <sandesh.patel@nutanix.com> --- src/qemu/qemu_capabilities.c | 117 ++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index d79941f6bd..d314956f46 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -4531,6 +4531,79 @@ virQEMUCapsLoadMachines(virQEMUCapsAccel *caps, } +static int +virQEMUCapsLoadCPUProps(virQEMUCaps *qemuCaps, + xmlXPathContextPtr ctxt) +{ + g_autoptr(qemuMonitorCPUPropsInfoList) cpuProps = NULL; + g_autofree xmlNodePtr *nodes = NULL; + int nprops; + size_t i; + + VIR_XPATH_NODE_AUTORESTORE(ctxt); + + if ((nprops = virXPathNodeSet("/qemuCaps/cpuPropertyInfo/property", + ctxt, &nodes)) < 0) + return -1; + + if (nprops == 0) + return 0; + + cpuProps = g_new0(qemuMonitorCPUPropsInfoList, 1); + cpuProps->nprops = nprops; + cpuProps->props = g_new0(qemuMonitorCPUPropsInfo, nprops); + + for (i = 0; i < (size_t) nprops; i++) { + qemuMonitorCPUPropsInfo *prop = cpuProps->props + i; + g_autofree char *type_str = NULL; + g_autofree xmlNodePtr *svsNodes = NULL; + int nsvs; + size_t j; + + if (!(prop->name = virXMLPropString(nodes[i], "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing property name in QEMU capabilities cache")); + return -1; + } + + if (!(type_str = virXMLPropString(nodes[i], "type"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing property type in QEMU capabilities cache for property '%1$s'"), + prop->name); + return -1; + } + if ((prop->type = qemuMonitorCPUPropertyTypeFromString(type_str)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown property type '%1$s' in QEMU capabilities cache for property '%2$s'"), + type_str, prop->name); + return -1; + } + + prop->composite = virXMLPropString(nodes[i], "composite"); + + ctxt->node = nodes[i]; + if ((nsvs = virXPathNodeSet("./supportedValue", ctxt, &svsNodes)) < 0) + return -1; + + if (nsvs == 0) + continue; + + prop->supportedValues = g_new0(char *, nsvs + 1); + for (j = 0; j < (size_t) nsvs; j++) { + if (!(prop->supportedValues[j] = virXMLPropString(svsNodes[j], "value"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing 'value' attribute in QEMU capabilities cache for property '%1$s'"), + prop->name); + return -1; + } + } + } + + qemuCaps->kvm.cpuProps = g_steal_pointer(&cpuProps); + return 0; +} + + static int virQEMUCapsLoadAccel(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt, @@ -5089,6 +5162,9 @@ virQEMUCapsLoadCache(virArch hostArch, virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_HYPERV); virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU); + if (virQEMUCapsLoadCPUProps(qemuCaps, ctxt) < 0) + return -1; + if (virXPathBoolean("boolean(./kvmSupportsNesting)", ctxt) > 0) qemuCaps->kvmSupportsNesting = true; @@ -5182,6 +5258,45 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsAccel *caps, } +static void +virQEMUCapsFormatCPUProps(virQEMUCapsAccel *caps, virBuffer *buf) +{ + qemuMonitorCPUPropsInfoList *cpuProps = caps->cpuProps; + size_t i; + + if (!cpuProps) + return; + + virBufferAddLit(buf, "<cpuPropertyInfo>\n"); + virBufferAdjustIndent(buf, 2); + + for (i = 0; i < cpuProps->nprops; i++) { + qemuMonitorCPUPropsInfo *prop = cpuProps->props + i; + + virBufferEscapeString(buf, "<property name='%s'", prop->name); + virBufferAsprintf(buf, " type='%s'", + qemuMonitorCPUPropertyTypeToString(prop->type)); + virBufferEscapeString(buf, " composite='%s'", prop->composite); + virBufferAddLit(buf, ">\n"); + + virBufferAdjustIndent(buf, 2); + if (prop->supportedValues) { + size_t j; + + for (j = 0; prop->supportedValues[j]; j++) { + virBufferEscapeString(buf, "<supportedValue value='%s'/>\n", + prop->supportedValues[j]); + } + } + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</property>\n"); + } + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</cpuPropertyInfo>\n"); +} + + static void virQEMUCapsFormatCPUModels(virArch arch, virQEMUCapsAccel *caps, @@ -5275,7 +5390,7 @@ virQEMUCapsFormatAccel(virQEMUCaps *qemuCaps, virQEMUCapsFormatHostCPUModelInfo(caps, buf, typeStr); virQEMUCapsFormatCPUModels(qemuCaps->arch, caps, buf, typeStr); virQEMUCapsFormatMachines(caps, buf, typeStr); - + virQEMUCapsFormatCPUProps(caps, buf); } -- 2.43.7