From: Sandesh Patel <[email protected]>

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 <[email protected]>
---
 src/qemu/qemu_capabilities.c                  | 120 +++++++++++++++++-
 .../caps_11.1.0_aarch64.xml                   |  13 ++
 2 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index cb933aa630..6c78e2a2da 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4531,6 +4531,82 @@ virQEMUCapsLoadMachines(virQEMUCapsAccel *caps,
 }
 
 
+static int
+virQEMUCapsLoadCPUProps(virQEMUCaps *qemuCaps,
+                        xmlXPathContextPtr ctxt)
+{
+    g_autoptr(qemuMonitorCPUPropsInfoList) cpuProps = NULL;
+    g_autofree char *xpath = NULL;
+    g_autofree xmlNodePtr *nodes = NULL;
+    int nprops;
+    size_t i;
+
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+
+    xpath = g_strdup("/qemuCaps/cpuPropertyInfo/property");
+    if ((nprops = virXPathNodeSet(xpath, 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;
+
+        prop->name = virXMLPropString(nodes[i], "name");
+        if (!prop->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++) {
+            prop->supportedValues[j] = virXMLPropString(svsNodes[j], "value");
+            if (!prop->supportedValues[j]) {
+                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 +5165,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 +5261,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 +5393,7 @@ virQEMUCapsFormatAccel(virQEMUCaps *qemuCaps,
     virQEMUCapsFormatHostCPUModelInfo(caps, buf, typeStr);
     virQEMUCapsFormatCPUModels(qemuCaps->arch, caps, buf, typeStr);
     virQEMUCapsFormatMachines(caps, buf, typeStr);
-
+    virQEMUCapsFormatCPUProps(caps, buf);
 }
 
 
diff --git a/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml 
b/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
index f2340830fd..ef7b5a6ae9 100644
--- a/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_11.1.0_aarch64.xml
@@ -362,6 +362,19 @@
   <machine type='kvm' name='netduinoplus2' maxCpus='1' 
defaultCPU='cortex-m4-arm-cpu' acpi='no'/>
   <machine type='kvm' name='collie' maxCpus='1' defaultCPU='sa1110-arm-cpu' 
defaultRAMid='strongarm.sdram' acpi='no'/>
   <machine type='kvm' name='raspi0' maxCpus='1' defaultRAMid='ram' acpi='no'/>
+  <cpuPropertyInfo>
+    <property name='hw_prop_WRPs' type='number'>
+      <supportedValue value='0-3'/>
+    </property>
+    <property name='hw_prop_API' type='string' composite='pauth'>
+      <supportedValue value='off'/>
+    </property>
+    <property name='feat_RAS' type='string'>
+      <supportedValue value='0.0'/>
+      <supportedValue value='1.0'/>
+      <supportedValue value='1.1_base'/>
+    </property>
+  </cpuPropertyInfo>
   <hostCPU type='tcg' model='max' migratability='no'>
     <property name='pauth-qarma5' type='boolean' value='false'/>
     <property name='sve768' type='boolean' value='true'/>
-- 
2.43.7

Reply via email to