- 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@xxxxxxxxxxx> --- 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