From: Akio Kakuno <fj333...@aa.jp.fujitsu.com>

- Add ARM CCA support in domain schema files.

Signed-off-by: Kazuhiro Abe <fj107...@aa.jp.fujitsu.com>
---
 src/conf/schemas/domaincaps.rng   |  36 ++++++++++
 src/conf/schemas/domaincommon.rng |  26 +++++++
 src/qemu/qemu_capabilities.c      | 113 ++++++++++++++++++++++++++++++
 src/qemu/qemu_capabilities.h      |   3 +
 4 files changed, 178 insertions(+)

diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng
index 595dbcd634..d8f88d20c3 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>
@@ -486,6 +489,39 @@
     </element>
   </define>
 
+  <define name="cca">
+    <element name="cca">
+      <ref name="supported"/>
+      <interleave>
+        <optional>
+          <attribute name="measurement-log">
+            <ref name="virYesNo"/>
+          </attribute>
+        </optional>
+        <optional>
+          <element name="enum">
+            <attribute name="name">
+              <value>measurement-algo</value>
+            </attribute>
+            <group>
+              <element name="value">
+                <value>sha256</value>
+              </element>
+              <element name="value">
+                <value>sha512</value>
+              </element>
+            </group>
+          </element>
+        </optional>
+        <optional>
+          <element name="personalization-value">
+            <text/>
+          </element>
+        </optional>
+      </interleave>
+    </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 5597d5a66b..50889297df 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -549,6 +549,9 @@
             <value>s390-pv</value>
           </attribute>
         </group>
+        <group>
+          <ref name="launchSecurityCCA"/>
+        </group>
       </choice>
     </element>
   </define>
@@ -644,6 +647,29 @@
       </optional>
     </interleave>
   </define>
+
+  <define name="launchSecurityCCA">
+    <attribute name="type">
+      <value>cca</value>
+    </attribute>
+    <interleave>
+      <optional>
+        <attribute name="measurement-log">
+          <ref name="virYesNo"/>
+        </attribute>
+      </optional>
+      <optional>
+        <element name="measurement-algo">
+          <data type="string"/>
+        </element>
+      </optional>
+      <optional>
+        <element name="personalization-value">
+          <data type="string"/>
+        </element>
+      </optional>
+    </interleave>
+  </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 8805e4a741..e6419f05af 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1970,6 +1970,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)
@@ -2045,6 +2073,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));
 
@@ -2686,6 +2717,13 @@ virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps)
 }
 
 
+virCCACapability *
+virQEMUCapsGetCCACapabilities(virQEMUCaps *qemuCaps)
+{
+    return qemuCaps->ccaCapabilities;
+}
+
+
 static int
 virQEMUCapsProbeQMPObjectTypes(virQEMUCaps *qemuCaps,
                                qemuMonitor *mon)
@@ -4572,6 +4610,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)
@@ -4892,6 +4962,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;
 
@@ -5132,6 +5205,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)
@@ -5240,6 +5330,9 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
     if (qemuCaps->sgxCapabilities)
         virQEMUCapsFormatSGXInfo(qemuCaps, &buf);
 
+    if (qemuCaps->ccaCapabilities)
+        virQEMUCapsFormatCCAInfo(qemuCaps, &buf);
+
     if (qemuCaps->hypervCapabilities)
         virQEMUCapsFormatHypervCapabilities(qemuCaps, &buf);
 
@@ -6763,6 +6856,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;
@@ -6960,6 +7055,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)
@@ -7031,6 +7143,7 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
     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 90ba9a2eed..e517368351 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -940,6 +940,9 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps);
 virSGXCapability *
 virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps);
 
+virCCACapability *
+virQEMUCapsGetCCACapabilities(virQEMUCaps *qemuCaps);
+
 bool
 virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) ATTRIBUTE_MOCKABLE;
 
-- 
2.43.5

Reply via email to