Add XML parsing and formatting support for PCI configuration:
- Add virDomainFeaturesPCIDefParseXML function
- Add virDomainFeaturesPCIDefFormat function
- Wire up parsing in virDomainFeaturesDefParse
- Wire up formatting in virDomainDefFormatFeatures
- Use g_steal_pointer for memory management
The highmem-mmio-size property can now be specified in domain XML
and will be properly parsed and formatted as a domain feature.
Signed-off-by: Matthew R. Ochs <mochs@nvidia.com>
---
src/conf/domain_conf.c | 101 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index acc30ffca765..126ae1e092b9 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -16967,6 +16967,48 @@ virDomainFeaturesTCGDefParse(virDomainDef *def,
}
+static virDomainPCIDef *
+virDomainPCIDefNew(void)
+{
+ virDomainPCIDef *pci;
+
+ pci = g_new0(virDomainPCIDef, 1);
+ return pci;
+}
+
+
+/**
+ * virDomainFeaturesPCIDefParseXML:
+ * @ctxt: XML context
+ *
+ * Parses PCI configuration from XML under features/pci. Currently only
+ * supports the highmem-mmio-size property for aarch64 virt machine types.
+ *
+ * Returns: parsed pci definition or NULL on error
+ */
+static virDomainPCIDef *
+virDomainFeaturesPCIDefParseXML(xmlXPathContextPtr ctxt)
+{
+ g_autoptr(virDomainPCIDef) pci = virDomainPCIDefNew();
+ unsigned long long size;
+ int rc;
+
+ if ((rc = virParseScaledValue("./features/pci/highmem-mmio-size",
+ NULL,
+ ctxt,
+ &size,
+ 1024 * 1024 * 1024, /* Default scale: GiB */
+ ULLONG_MAX,
+ false)) < 0)
+ return NULL;
+
+ if (rc == 1)
+ pci->highmemMMIOSize = size;
+
+ return g_steal_pointer(&pci);
+}
+
+
static int
virDomainFeaturesDefParse(virDomainDef *def,
xmlXPathContextPtr ctxt)
@@ -17213,6 +17255,13 @@ virDomainFeaturesDefParse(virDomainDef *def,
break;
}
+ case VIR_DOMAIN_FEATURE_PCI:
+ if ((def->pci = virDomainFeaturesPCIDefParseXML(ctxt)) == NULL)
+ return -1;
+
+ def->features[val] = VIR_TRISTATE_SWITCH_ON;
+ break;
+
case VIR_DOMAIN_FEATURE_LAST:
break;
}
@@ -21195,6 +21244,25 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
}
break;
+ case VIR_DOMAIN_FEATURE_PCI:
+ if (src->features[i] != dst->features[i]) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("target domain pci feature %1$s does not match source %2$s"),
+ virTristateSwitchTypeToString(dst->features[i]),
+ virTristateSwitchTypeToString(src->features[i]));
+ return false;
+ }
+ if (src->features[i] == VIR_TRISTATE_SWITCH_ON) {
+ if (src->pci->highmemMMIOSize != dst->pci->highmemMMIOSize) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("target domain pci highmem-mmio-size %1$llu does not match source %2$llu"),
+ dst->pci->highmemMMIOSize,
+ src->pci->highmemMMIOSize);
+ return false;
+ }
+ }
+ break;
+
case VIR_DOMAIN_FEATURE_MSRS:
case VIR_DOMAIN_FEATURE_TCG:
case VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN:
@@ -27903,6 +27971,34 @@ virDomainFeatureTCGFormat(virBuffer *buf,
}
+/**
+ * virDomainFeaturesPCIDefFormat:
+ * @buf: buffer to write XML data to
+ * @pci: PCI feature data to format
+ *
+ * Format the PCI feature configuration as XML under features/pci.
+ */
+static void
+virDomainFeaturesPCIDefFormat(virBuffer *buf,
+ const virDomainPCIDef *pci)
+{
+ g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+ g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
+
+ if (!pci)
+ return;
+
+ if (pci->highmemMMIOSize > 0) {
+ virBufferAddLit(&attrBuf, " unit='G'");
+ virBufferAsprintf(&childBuf, "<highmem-mmio-size%s>%llu</highmem-mmio-size>\n",
+ virBufferCurrentContent(&attrBuf),
+ pci->highmemMMIOSize / (1024 * 1024 * 1024));
+ }
+
+ virXMLFormatElement(buf, "pci", NULL, &childBuf);
+}
+
+
static int
virDomainDefFormatFeatures(virBuffer *buf,
virDomainDef *def)
@@ -28261,6 +28357,11 @@ virDomainDefFormatFeatures(virBuffer *buf,
virDomainAIATypeToString(def->features[i]));
break;
+ case VIR_DOMAIN_FEATURE_PCI:
+ if (def->features[i] == VIR_TRISTATE_SWITCH_ON)
+ virDomainFeaturesPCIDefFormat(&childBuf, def->pci);
+ break;
+
case VIR_DOMAIN_FEATURE_LAST:
break;
}
--
2.46.0