- 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: Akio Kakuno <fj3333bs(a)fujitsu.com>
---
docs/formatdomain.rst | 28 ++++++++++++++++++++++++++++
src/conf/domain_capabilities.h | 6 ++++++
src/conf/domain_conf.c | 7 +++++++
src/conf/domain_conf.h | 7 +++++++
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 | 32 ++++++++++++++++++++++++++++++++
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, 105 insertions(+)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 620daae9af..917e7e2cf5 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9185,6 +9185,34 @@ 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-algo>sha256</measurement-algo>
+ </launchSecurity>
+ ...
+ </domain>
+
+The ``<launchSecurity/>`` element accepts the following attributes:
+
+``measurement-algo``
+ The optional ``measurement-algo`` element determines algorithm used to
+ describe blob hashes.
+
+
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 3f88a77a8f..231073e472 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1529,6 +1529,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
"sev",
"sev-snp",
"s390-pv",
+ "cca",
);
VIR_ENUM_IMPL(virDomainPstoreBackend,
@@ -3881,6 +3882,9 @@ 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);
+ break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -13904,6 +13908,8 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+ break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
default:
@@ -27181,6 +27187,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 9f7c28343f..f088227e4d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2895,6 +2895,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;
@@ -2929,11 +2930,17 @@ struct _virDomainSEVSNPDef {
};
+struct _virDomainCCADef {
+ char *measurement_algo;
+};
+
+
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 6aed74dd8d..b8fcbbd367 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1860,6 +1860,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 59be61cea4..6e23d09983 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -216,6 +216,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 53aa64a009..b0283c0119 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -725,6 +725,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
/* 470 */
"migrate-incoming.exit-on-error", /*
QEMU_CAPS_MIGRATE_INCOMING_EXIT_ON_ERROR */
+ "rme-guest", /* QEMU_CAPS_CCA_GUEST */
);
@@ -810,6 +811,8 @@ struct _virQEMUCaps {
virSGXCapability *sgxCapabilities;
+ virCCACapability *ccaCapabilities;
+
virDomainCapsFeatureHyperv *hypervCapabilities;
/* Capabilities which may differ depending on the accelerator. */
@@ -1413,6 +1416,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "virtio-sound-device", QEMU_CAPS_DEVICE_VIRTIO_SOUND },
{ "sev-snp-guest", QEMU_CAPS_SEV_SNP_GUEST },
{ "acpi-erst", QEMU_CAPS_DEVICE_ACPI_ERST },
+ { "rme-guest", QEMU_CAPS_CCA_GUEST },
};
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 398749a136..21081d5fbc 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -704,6 +704,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check
*/
/* 470 */
QEMU_CAPS_MIGRATE_INCOMING_EXIT_ON_ERROR, /* exit-on-error argument of
migrate-incoming command */
+ 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 f3c85d65e8..3825a68930 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -864,6 +864,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 1f28de6194..e2dd99fca8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6924,6 +6924,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);
@@ -9679,6 +9682,32 @@ qemuBuildPVCommandLine(virDomainObj *vm, virCommand *cmd)
}
+static int
+qemuBuildCCACommandLine(virDomainObj *vm, virCommand *cmd,
+ virDomainCCADef *cca)
+{
+ g_autoptr(virJSONValue) props = NULL;
+ qemuDomainObjPrivate *priv = vm->privateData;
+
+ VIR_DEBUG("measurement_algorithm=%s", cca->measurement_algo);
+
+ if (cca->measurement_algo) {
+ if (qemuMonitorCreateObjectProps(&props, "rme-guest",
"rme0",
+ "S:measurement-algorithm",
cca->measurement_algo,
+ NULL) < 0)
+ return -1;
+ } else {
+ if (qemuMonitorCreateObjectProps(&props, "rme-guest",
"rme0", NULL) < 0)
+ return -1;
+ }
+
+ if (qemuBuildObjectCommandlineFromJSON(cmd, props, priv->qemuCaps) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static int
qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
virDomainSecDef *sec)
@@ -9696,6 +9725,9 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
return qemuBuildPVCommandLine(vm, cmd);
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+ return qemuBuildCCACommandLine(vm, cmd, &sec->data.cca);
+ break;
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 d2eddbd9ae..1c779ff619 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19155,6 +19155,8 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
if (qemuDomainGetSEVInfo(vm, params, nparams, 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 6db48b0e7b..c82e359e25 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6845,6 +6845,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:
@@ -6917,6 +6919,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 086c66b602..26d0f9dada 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1368,6 +1368,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 0505f4e4a3..6364d3fffc 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:
@@ -2258,6 +2259,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.34.1