Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
libvirt (10.7.0-3deepin4) unstable; urgency=medium

* feat: Add support for ARM-CCA confidential computing features

-- WangYuli <wangyuli@aosc.io> Fri, 05 Dec 2025 14:15:35 +0800

libvirt (10.7.0-3deepin3) unstable; urgency=medium

* feat: add sw64 support
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,384 @@
From 0c394e3cd79402a9a0741b3ca980379f1cc78a5e Mon Sep 17 00:00:00 2001
From: WangYuli <wangyuli@aosc.io>
Date: Fri, 5 Dec 2025 12:46:45 +0800
Subject: [PATCH 1/3] src: Add ARM CCA support in qemu driver to launch VM

bugzilla:https://gitee.com/openeuler/libvirt/issues/ICU4UF?from=project-issue
reference:https://patchew.org/Libvirt/20250612071418.2926384-1-fj1078ii@aa.jp.fujitsu.com/

--------------------------------

src: Add ARM CCA support in qemu driver to launch VM

- 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@aa.jp.fujitsu.com>
Signed-off-by: rpm-build <rpm-build>
Signed-off-by: WangYuli <wangyuli@aosc.io>
---
docs/formatdomain.rst | 43 ++++++++++++++++++++++++++++++++++
src/conf/domain_capabilities.h | 6 +++++
src/conf/domain_conf.c | 25 ++++++++++++++++++++
src/conf/domain_conf.h | 9 +++++++
src/conf/virconftypes.h | 2 ++
src/qemu/qemu_capabilities.c | 6 +++++
src/qemu/qemu_capabilities.h | 3 +++
src/qemu/qemu_command.c | 28 ++++++++++++++++++++++
src/qemu/qemu_firmware.c | 1 +
src/qemu/qemu_namespace.c | 2 ++
src/qemu/qemu_process.c | 4 ++++
src/qemu/qemu_validate.c | 4 ++++
12 files changed, 133 insertions(+)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 47d3e212..3b169a01 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -9028,6 +9028,49 @@ The ``<launchSecurity/>`` element then accepts the following child elements:
blob to provide to the guest, as documented for the 'HOST_DATA' parameter of
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 2a4596ac..01076c32 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -239,6 +239,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 cc2c606b..b90b766d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1515,6 +1515,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
"sev",
"sev-snp",
"s390-pv",
+ "cca",
);

VIR_ENUM_IMPL(virDomainPstoreBackend,
@@ -3868,6 +3869,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:
@@ -13791,6 +13796,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)
@@ -13816,6 +13836,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:
@@ -26977,6 +27001,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 439429db..f16ffa0c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2870,6 +2870,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;
@@ -2907,11 +2908,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/virconftypes.h b/src/conf/virconftypes.h
index f18ebcca..76218f51 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 0da12800..d3bd015e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -715,6 +715,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
"acpi-erst", /* QEMU_CAPS_DEVICE_ACPI_ERST */
"intel-iommu.dma-translation", /* QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION */
"machine-i8042-opt", /* QEMU_CAPS_MACHINE_I8042_OPT */
+
+ /* 465 */
+ "rme-guest", /* QEMU_CAPS_CCA_GUEST */
);


@@ -800,6 +803,8 @@ struct _virQEMUCaps {

virSGXCapability *sgxCapabilities;

+ virCCACapability *ccaCapabilities;
+
virDomainCapsFeatureHyperv *hypervCapabilities;

/* Capabilities which may differ depending on the accelerator. */
@@ -1406,6 +1411,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 5036d49a..1eb94f41 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -695,6 +695,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION, /* intel-iommu.dma-translation */
QEMU_CAPS_MACHINE_I8042_OPT, /* -machine xxx,i8042=on/off; use virQEMUCapsSupportsI8042Toggle() to query this capability */

+ /* 465 */
+ QEMU_CAPS_CCA_GUEST, /* -object rme-guest */
+
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 8d4016a5..dee0b738 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7085,6 +7085,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);
@@ -9849,6 +9852,29 @@ qemuBuildPVCommandLine(virDomainObj *vm, virCommand *cmd)
}


+static int
+qemuBuildCCACommandLine(virCommand *cmd, virDomainCCADef *cca, qemuDomainObjPrivate *priv)
+{
+ 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, priv->qemuCaps) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static int
qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
virDomainSecDef *sec)
@@ -9866,6 +9892,8 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
return qemuBuildPVCommandLine(vm, cmd);
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
+ return qemuBuildCCACommandLine(cmd, &sec->data.cca, vm->privateData);
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index 914f8596..9bf57164 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 bbe3d5a1..69295306 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -660,6 +660,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 d29839c5..0f264f53 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6757,6 +6757,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:
@@ -6839,6 +6841,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 3c40f76c..b18573d5 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1365,6 +1365,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);
--
2.51.0

Loading
Loading