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

- Add ARM CCA support to the qemu driver for aarch64 systems.

[XML example]
<domain>
  ...
  <launchsecurity type='cca'>
    <measurement-algo>sha256</measurement-algo>
  </launchsecurity>
  ...
</domain>

Signed-off-by: Kazuhiro Abe <fj107...@aa.jp.fujitsu.com>
---
 docs/formatdomain.rst          | 43 ++++++++++++++++++++++++++++++++++
 src/conf/domain_capabilities.h |  6 +++++
 src/conf/domain_conf.c         | 25 ++++++++++++++++++++
 src/conf/domain_conf.h         |  9 +++++++
 src/conf/domain_validate.c     |  1 +
 src/conf/virconftypes.h        |  2 ++
 src/qemu/qemu_capabilities.c   |  4 ++++
 src/qemu/qemu_capabilities.h   |  1 +
 src/qemu/qemu_cgroup.c         |  2 ++
 src/qemu/qemu_command.c        | 29 +++++++++++++++++++++++
 src/qemu/qemu_driver.c         |  2 ++
 src/qemu/qemu_firmware.c       |  1 +
 src/qemu/qemu_namespace.c      |  2 ++
 src/qemu/qemu_process.c        |  4 ++++
 src/qemu/qemu_validate.c       |  4 ++++
 src/security/security_dac.c    |  2 ++
 16 files changed, 137 insertions(+)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index c7c75ae219..222967a7a4 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9487,6 +9487,49 @@ The ``<launchSecurity/>`` element then accepts the 
following child elements:
    the SNP_LAUNCH_FINISH command in the SEV-SNP firmware ABI.
 
 
+The contents of the ``<launchSecurity type='cca'>`` element is used to create
+RealmVM using the Arm CCA feature (Confidential Compute Architecture).
+CCA :since:`Since 11.0.0` enhances the virtualization capabilities of the
+platform by separating the management of resources from access to those 
resources.
+This is achieved by extending the TrustZone of Cortex-A's Normal and Secure
+world concepts and adding the Realm world and the underlying Root world.
+The Secure Monitor runs in the root world and manages the transition between
+these security states. For more information see the Learn the architecture -
+Arm Confidential Compute Architecture software stack:
+`<https://developer.arm.com/documentation/den0127/latest>`__
+
+::
+
+  <domain>
+    ...
+    <launchSecurity type='cca' measurement-log='yes'>
+      <measurement-algo>sha256</measurement-algo>
+      <personalization-value>...</personalization-value>
+    </launchSecurity>
+    ...
+  </domain>
+
+The ``<launchSecurity/>`` element accepts the following attributes:
+
+``measurement-algo``
+   The optional ``measurement-algo`` element determines algorithm used to
+   describe blob hashes.
+
+``personalization-value``
+   The optional ``personalization-value`` element is used to configure
+   the Realm Personalization Value (RPV). The Realm Personalization
+   Value (RPV) is provided by the user to distinguish Realms that have
+   the same initial measurement. The personalization-value for libvirt
+   must be an 88-character string representing the Base64 encoding of
+   the 64-byte hexadecimal value defined in the RMM specification.
+   Ensure that you encode the 64-byte hex value from the RMM specification
+   using Base64 before providing it to libvirt.
+
+``measurement-log``
+   The optional ``measurement-log`` element provides a way to create
+   an event log in the format defined by the Trusted Computing Group
+   for TPM2.
+
 Example configs
 ===============
 
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 69dd1a15c1..93e2cc2931 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -240,6 +240,12 @@ struct _virSGXCapability {
     virSGXSection *sgxSections;
 };
 
+typedef struct _virCCACapability virCCACapability;
+struct _virCCACapability {
+    size_t nCcaMeasurementAlgo;
+    char **ccaMeasurementAlgo;
+};
+
 STATIC_ASSERT_ENUM(VIR_DOMAIN_CRYPTO_MODEL_LAST);
 STATIC_ASSERT_ENUM(VIR_DOMAIN_CRYPTO_TYPE_LAST);
 STATIC_ASSERT_ENUM(VIR_DOMAIN_CRYPTO_BACKEND_LAST);
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b3b0bd7329..5b298e57e5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1538,6 +1538,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
               "sev",
               "sev-snp",
               "s390-pv",
+              "cca",
 );
 
 VIR_ENUM_IMPL(virDomainPstoreBackend,
@@ -3949,6 +3950,10 @@ virDomainSecDefFree(virDomainSecDef *def)
         g_free(def->data.sev_snp.id_auth);
         g_free(def->data.sev_snp.host_data);
         break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+        g_free(def->data.cca.measurement_algo);
+        g_free(def->data.cca.personalization_value);
+        break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -14174,6 +14179,21 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def,
 }
 
 
+static int
+virDomainCCADefParseXML(virDomainCCADef *def,
+                        xmlXPathContextPtr ctxt)
+{
+    def->measurement_algo = virXPathString("string(./measurement-algo)", ctxt);
+    def->personalization_value = 
virXPathString("string(./personalization-value)", ctxt);
+
+    if (virXMLPropTristateBool(ctxt->node, "measurement-log", 
VIR_XML_PROP_NONE,
+                               &def->measurement_log) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 static virDomainSecDef *
 virDomainSecDefParseXML(xmlNodePtr lsecNode,
                         xmlXPathContextPtr ctxt)
@@ -14199,6 +14219,10 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
         break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+        if (virDomainCCADefParseXML(&sec->data.cca, ctxt) < 0)
+            return NULL;
+        break;
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
     default:
@@ -27630,6 +27654,7 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef 
*sec)
         break;
 
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+    case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
         break;
 
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 58b97a2b54..2a4ab6e2eb 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2956,6 +2956,7 @@ typedef enum {
     VIR_DOMAIN_LAUNCH_SECURITY_SEV,
     VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP,
     VIR_DOMAIN_LAUNCH_SECURITY_PV,
+    VIR_DOMAIN_LAUNCH_SECURITY_CCA,
 
     VIR_DOMAIN_LAUNCH_SECURITY_LAST,
 } virDomainLaunchSecurity;
@@ -2990,11 +2991,19 @@ struct _virDomainSEVSNPDef {
 };
 
 
+struct _virDomainCCADef {
+    char *measurement_algo;
+    char *personalization_value;
+    virTristateBool measurement_log;
+};
+
+
 struct _virDomainSecDef {
     virDomainLaunchSecurity sectype;
     union {
         virDomainSEVDef sev;
         virDomainSEVSNPDef sev_snp;
+        virDomainCCADef cca;
     } data;
 };
 
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index d0d4bc0bf4..452236b9db 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1934,6 +1934,7 @@ virDomainDefLaunchSecurityValidate(const virDomainDef 
*def)
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+    case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
         break;
     }
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index c70437bc05..fd6f54a654 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -220,6 +220,8 @@ typedef struct _virDomainSEVDef virDomainSEVDef;
 
 typedef struct _virDomainSEVSNPDef virDomainSEVSNPDef;
 
+typedef struct _virDomainCCADef virDomainCCADef;
+
 typedef struct _virDomainSecDef virDomainSecDef;
 
 typedef struct _virDomainShmemDef virDomainShmemDef;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index c24584bf75..9b6ea5f57d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -732,6 +732,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
 
               /* 475 */
               "virtio-scsi.iothread-mapping", /* 
QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING */
+              "rme-guest", /* QEMU_CAPS_CCA_GUEST */
     );
 
 
@@ -817,6 +818,8 @@ struct _virQEMUCaps {
 
     virSGXCapability *sgxCapabilities;
 
+    virCCACapability *ccaCapabilities;
+
     virDomainCapsFeatureHyperv *hypervCapabilities;
 
     /* Capabilities which may differ depending on the accelerator. */
@@ -1419,6 +1422,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
     { "sev-snp-guest", QEMU_CAPS_SEV_SNP_GUEST },
     { "acpi-erst", QEMU_CAPS_DEVICE_ACPI_ERST },
     { "virtio-mem-ccw", QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW },
+    { "rme-guest", QEMU_CAPS_CCA_GUEST },
 };
 
 
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 40aa7acef4..90ba9a2eed 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -713,6 +713,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 
     /* 475 */
     QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING, /* virtio-scsi supports 
per-virtqueue iothread mapping */
+    QEMU_CAPS_CCA_GUEST, /* -object rme-guest */
 
     QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 48af467bf9..437c8d71fb 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -862,6 +862,8 @@ qemuSetupDevicesCgroup(virDomainObj *vm)
             if (qemuSetupSEVCgroup(vm) < 0)
                 return -1;
             break;
+        case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+            break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index bf03561fde..2229525260 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7044,6 +7044,9 @@ qemuBuildMachineCommandLine(virCommand *cmd,
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
             virBufferAddLit(&buf, ",confidential-guest-support=lsec0");
             break;
+        case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+            virBufferAddLit(&buf, ",confidential-guest-support=rme0");
+            break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
             virReportEnumRangeError(virDomainLaunchSecurity, 
def->sec->sectype);
@@ -9790,6 +9793,29 @@ qemuBuildPVCommandLine(virCommand *cmd)
 }
 
 
+static int
+qemuBuildCCACommandLine(virCommand *cmd, virDomainCCADef *cca)
+{
+    g_autoptr(virJSONValue) props = NULL;
+
+    VIR_DEBUG("measurement_algorithm=%s personalization_value=%s 
measurement_log=%d",
+              cca->measurement_algo, cca->personalization_value,
+              cca->measurement_log);
+
+    if (qemuMonitorCreateObjectProps(&props, "rme-guest", "rme0",
+                                     "S:measurement-algorithm", 
cca->measurement_algo,
+                                     "S:personalization-value", 
cca->personalization_value,
+                                     "T:measurement-log", cca->measurement_log,
+                                     NULL) < 0)
+        return -1;
+
+    if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 static int
 qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
                         virDomainSecDef *sec)
@@ -9807,6 +9833,9 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
         return qemuBuildPVCommandLine(cmd);
 
+    case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+        return qemuBuildCCACommandLine(cmd, &sec->data.cca);
+
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
     case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
         virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a34d6f1437..ce58abae28 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19280,6 +19280,8 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
         if (qemuDomainGetSEVInfo(vm, list, flags) < 0)
             goto cleanup;
         break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+        break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index 2d0ec0b4fa..c670ad11b0 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -1371,6 +1371,7 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
             }
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+        case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index 59421ec9d1..61c575e96a 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -664,6 +664,8 @@ qemuDomainSetupLaunchSecurity(virDomainObj *vm,
 
         VIR_DEBUG("Set up launch security for SEV");
         break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+        break;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
         break;
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7fe49adfb4..9460e9e4e7 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7011,6 +7011,8 @@ qemuProcessPrepareDomain(virQEMUDriver *driver,
             if (qemuProcessUpdateSEVInfo(vm) < 0)
                 return -1;
             break;
+        case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+            break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
@@ -7083,6 +7085,8 @@ qemuProcessPrepareLaunchSecurityGuestInput(virDomainObj 
*vm)
         return qemuProcessPrepareSEVGuestInput(vm);
     case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP:
         break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+        return 0;
     case VIR_DOMAIN_LAUNCH_SECURITY_PV:
         return 0;
     case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index b2c3c9e2f6..bb88a3b4aa 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1413,6 +1413,10 @@ qemuValidateDomainDef(const virDomainDef *def,
                 return -1;
             }
             break;
+
+        case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+            break;
+
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
             virReportEnumRangeError(virDomainLaunchSecurity, 
def->sec->sectype);
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 3ecbc7277d..81578c1625 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -2017,6 +2017,7 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr,
                 rc = -1;
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+        case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -2263,6 +2264,7 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr,
                 return -1;
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+        case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
             break;
         case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
         case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
-- 
2.43.5

Reply via email to