From: Akio Kakuno <fj3333bs(a)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 <fj1078ii(a)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