- Add ARM CCA support in domain schema files.
Signed-off-by: Akio Kakuno <fj3333bs(a)fujitsu.com>
---
src/conf/domain_conf.c | 9 +++
src/conf/schemas/domaincaps.rng | 14 ++++
src/conf/schemas/domaincommon.rng | 14 ++++
src/qemu/qemu_capabilities.c | 113 ++++++++++++++++++++++++++++++
src/qemu/qemu_capabilities.h | 3 +
5 files changed, 153 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 231073e472..91cc8a5869 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13883,6 +13883,14 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def,
}
+static void
+virDomainCCADefParseXML(virDomainCCADef *def,
+ xmlXPathContextPtr ctxt)
+{
+ def->measurement_algo = virXPathString("string(./measurement-algo)",
ctxt);
+}
+
+
static virDomainSecDef *
virDomainSecDefParseXML(xmlNodePtr lsecNode,
xmlXPathContextPtr ctxt)
@@ -13909,6 +13917,7 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+ virDomainCCADefParseXML(&sec->data.cca, ctxt);
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng
index 3559d2ae05..4826900258 100644
--- a/src/conf/schemas/domaincaps.rng
+++ b/src/conf/schemas/domaincaps.rng
@@ -363,6 +363,9 @@
<optional>
<ref name="sgx"/>
</optional>
+ <optional>
+ <ref name="cca"/>
+ </optional>
<optional>
<ref name="hyperv"/>
</optional>
@@ -481,6 +484,17 @@
</element>
</define>
+ <define name="cca">
+ <element name="cca">
+ <ref name="supported"/>
+ <optional>
+ <element name="measurement-algo">
+ <text/>
+ </element>
+ </optional>
+ </element>
+ </define>
+
<define name="hyperv">
<element name="hyperv">
<ref name="supported"/>
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 7121519ca3..b340381295 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -528,6 +528,9 @@
<value>s390-pv</value>
</attribute>
</group>
+ <group>
+ <ref name="launchSecurityCCA"/>
+ </group>
</choice>
</element>
</define>
@@ -623,6 +626,17 @@
</optional>
</interleave>
</define>
+
+ <define name="launchSecurityCCA">
+ <attribute name="type">
+ <value>cca</value>
+ </attribute>
+ <optional>
+ <element name="measurement-algo">
+ <data type="string"/>
+ </element>
+ </optional>
+ </define>
<!--
Enable or disable perf events for the domain. For each
of the events the following rules apply:
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 4534f18a24..523fe05289 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1962,6 +1962,34 @@ virQEMUCapsSGXInfoCopy(virSGXCapability **dst,
}
+static void
+virQEMUCapsCCAInfoCopy(virCCACapability **dst,
+ virCCACapability *src)
+{
+ g_autoptr(virCCACapability) tmp = NULL;
+ size_t i;
+
+ if (!src) {
+ *dst = NULL;
+ return;
+ }
+
+ tmp = g_new0(virCCACapability, 1);
+
+ tmp->nCcaMeasurementAlgo = src->nCcaMeasurementAlgo;
+
+ if (tmp->nCcaMeasurementAlgo != 0) {
+ tmp->ccaMeasurementAlgo = g_new0(char *, tmp->nCcaMeasurementAlgo);
+
+ for (i = 0; i < tmp->nCcaMeasurementAlgo; i++) {
+ tmp->ccaMeasurementAlgo[i] = g_strdup(src->ccaMeasurementAlgo[i]);
+ }
+ }
+
+ *dst = g_steal_pointer(&tmp);
+}
+
+
static void
virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccel *dst,
virQEMUCapsAccel *src)
@@ -2037,6 +2065,9 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps)
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC))
virQEMUCapsSGXInfoCopy(&ret->sgxCapabilities,
qemuCaps->sgxCapabilities);
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCA_GUEST))
+ virQEMUCapsCCAInfoCopy(&ret->ccaCapabilities,
qemuCaps->ccaCapabilities);
+
ret->hypervCapabilities = g_memdup(qemuCaps->hypervCapabilities,
sizeof(virDomainCapsFeatureHyperv));
@@ -2678,6 +2709,13 @@ virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps)
}
+virCCACapability *
+virQEMUCapsGetCCACapabilities(virQEMUCaps *qemuCaps)
+{
+ return qemuCaps->ccaCapabilities;
+}
+
+
static int
virQEMUCapsProbeQMPObjectTypes(virQEMUCaps *qemuCaps,
qemuMonitor *mon)
@@ -4563,6 +4601,38 @@ virQEMUCapsParseSGXInfo(virQEMUCaps *qemuCaps,
}
+static int
+virQEMUCapsParseCCAInfo(virQEMUCaps *qemuCaps,
+ xmlXPathContextPtr ctxt)
+{
+ g_autofree xmlNodePtr *nodes = NULL;
+ size_t i;
+ int n;
+
+ if ((n = virXPathNodeSet("./cca", ctxt, &nodes)) < 0)
+ return -1;
+
+ if (n > 0) {
+ g_autoptr(virCCACapability) tmp = g_new0(virCCACapability, 1);
+ tmp->ccaMeasurementAlgo = g_new0(char *, n);
+
+ for (i = 0; i < n; i++) {
+ char *malgo = NULL;
+ if (!(malgo = virXMLPropString(nodes[i], "measurement-algo"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing CCA measurement-algo in QEMU capabilities
cache"));
+ return -1;
+ }
+
+ tmp->ccaMeasurementAlgo[i] = g_strdup(malgo);
+ }
+ tmp->nCcaMeasurementAlgo = n;
+ qemuCaps->ccaCapabilities = g_steal_pointer(&tmp);
+ }
+ return 0;
+}
+
+
static int
virQEMUCapsParseHypervCapabilities(virQEMUCaps *qemuCaps,
xmlXPathContextPtr ctxt)
@@ -4883,6 +4953,9 @@ virQEMUCapsLoadCache(virArch hostArch,
if (virQEMUCapsParseSGXInfo(qemuCaps, ctxt) < 0)
return -1;
+ if (virQEMUCapsParseCCAInfo(qemuCaps, ctxt) < 0)
+ return -1;
+
if (virQEMUCapsParseHypervCapabilities(qemuCaps, ctxt) < 0)
return -1;
@@ -5123,6 +5196,23 @@ virQEMUCapsFormatSGXInfo(virQEMUCaps *qemuCaps,
}
+static void
+virQEMUCapsFormatCCAInfo(virQEMUCaps *qemuCaps, virBuffer *buf)
+{
+ virCCACapability *cca = virQEMUCapsGetCCACapabilities(qemuCaps);
+ size_t i;
+ size_t n;
+
+ n = cca->nCcaMeasurementAlgo;
+
+ if (n != 0) {
+ for (i = 0; i < n; i++) {
+ virBufferAsprintf(buf, "<cca
measurement-algo='%s'/>\n", cca->ccaMeasurementAlgo[i]);
+ }
+ }
+}
+
+
static void
virQEMUCapsFormatHypervCapabilities(virQEMUCaps *qemuCaps,
virBuffer *buf)
@@ -5231,6 +5321,9 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
if (qemuCaps->sgxCapabilities)
virQEMUCapsFormatSGXInfo(qemuCaps, &buf);
+ if (qemuCaps->ccaCapabilities)
+ virQEMUCapsFormatCCAInfo(qemuCaps, &buf);
+
if (qemuCaps->hypervCapabilities)
virQEMUCapsFormatHypervCapabilities(qemuCaps, &buf);
@@ -6757,6 +6850,8 @@ virQEMUCapsFillDomainLaunchSecurity(virQEMUCaps *qemuCaps,
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_S390_PV_GUEST) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT))
VIR_DOMAIN_CAPS_ENUM_SET(launchSecurity->sectype,
VIR_DOMAIN_LAUNCH_SECURITY_PV);
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCA_GUEST))
+ VIR_DOMAIN_CAPS_ENUM_SET(launchSecurity->sectype,
VIR_DOMAIN_LAUNCH_SECURITY_CCA);
if (launchSecurity->sectype.values == 0) {
launchSecurity->supported = VIR_TRISTATE_BOOL_NO;
@@ -6954,6 +7049,23 @@ virQEMUCapsFillDomainFeatureSGXCaps(virQEMUCaps *qemuCaps,
}
+/**
+ * virQEMUCapsFillDomainFeatureCCACaps:
+ * @qemuCaps: QEMU capabilities
+ * @domCaps: domain capabilities
+ *
+ * Take the information about CCA capabilities that has been obtained
+ * using the 'query-cca-capabilities' QMP command and stored in @qemuCaps
+ * and convert it to a form suitable for @domCaps.
+ */
+static void
+virQEMUCapsFillDomainFeatureCCACaps(virQEMUCaps *qemuCaps,
+ virDomainCaps *domCaps)
+{
+ virQEMUCapsCCAInfoCopy(&domCaps->cca, qemuCaps->ccaCapabilities);
+}
+
+
static void
virQEMUCapsFillDomainFeatureHypervCaps(virQEMUCaps *qemuCaps,
virDomainCaps *domCaps)
@@ -7024,6 +7136,7 @@ virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps,
virQEMUCapsFillDomainFeatureS390PVCaps(qemuCaps, domCaps);
virQEMUCapsFillDomainFeaturePS2Caps(qemuCaps, domCaps);
virQEMUCapsFillDomainFeatureSGXCaps(qemuCaps, domCaps);
+ virQEMUCapsFillDomainFeatureCCACaps(qemuCaps, domCaps);
virQEMUCapsFillDomainFeatureHypervCaps(qemuCaps, domCaps);
virQEMUCapsFillDomainDeviceCryptoCaps(qemuCaps, crypto);
virQEMUCapsFillDomainLaunchSecurity(qemuCaps, launchSecurity);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 21081d5fbc..effee475f6 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -931,6 +931,9 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps);
virSGXCapability *
virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps);
+virCCACapability *
+virQEMUCapsGetCCACapabilities(virQEMUCaps *qemuCaps);
+
bool
virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_NO_INLINE;
--
2.34.1