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
© 2016 - 2026 Red Hat, Inc.