Skip to content

Commit 42e075b

Browse files
Avenger-285714Zeno-sole
authored andcommitted
feat: Add support for ARM-CCA confidential computing features
[ Feature description ] Confidential computing changes the traditional trust model by reducing the amount of trust users must place in the compute infrastructure (for example, the OS or hypervisor). It runs workloads inside a hardware-backed trusted execution environment to protect data-in-use, preventing privileged software and hardware agents from observing or tampering with data and code. ARM’s Confidential Compute Architecture (CCA) is an architectural extension that provides confidential computing capabilities. Its main features include: *1. Introducing a confidential execution environment called Realm to protect in-use data and code. 2. Allowing any third-party developer to protect their VMs or applications. 3. Supporting dynamic memory allocation. 4. Supporting remote attestation. Compared with the earlier TrustZone technology, CCA can provide security at the confidential-VM level and supports seamless migration of large applications. For more details, see ARM’s official page. [1] The Host/KVM must manage Realm lifecycle, allocate and reclaim Realm resources, and schedule Realms via the Realm Management Interface (RMI). The kernel/KVM will need corresponding patches to support CCA. [ Affected repositories ] kernel, libvirt, QEMU. [1]. https://www.arm.com/architecture/security-features/arm-confidential-compute-architecture Link: https://gitee.com/opencloudos-stream/libvirt/pulls/22 Signed-off-by: WangYuli <wangyuli@aosc.io>
1 parent b3aabd5 commit 42e075b

5 files changed

Lines changed: 2298 additions & 0 deletions

debian/changelog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
libvirt (10.7.0-3deepin4) unstable; urgency=medium
2+
3+
* feat: Add support for ARM-CCA confidential computing features
4+
5+
-- WangYuli <wangyuli@aosc.io> Fri, 05 Dec 2025 14:15:35 +0800
6+
17
libvirt (10.7.0-3deepin3) unstable; urgency=medium
28

39
* feat: add sw64 support
Lines changed: 384 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
From 0c394e3cd79402a9a0741b3ca980379f1cc78a5e Mon Sep 17 00:00:00 2001
2+
From: WangYuli <wangyuli@aosc.io>
3+
Date: Fri, 5 Dec 2025 12:46:45 +0800
4+
Subject: [PATCH 1/3] src: Add ARM CCA support in qemu driver to launch VM
5+
6+
bugzilla:https://gitee.com/openeuler/libvirt/issues/ICU4UF?from=project-issue
7+
reference:https://patchew.org/Libvirt/20250612071418.2926384-1-fj1078ii@aa.jp.fujitsu.com/
8+
9+
--------------------------------
10+
11+
src: Add ARM CCA support in qemu driver to launch VM
12+
13+
- Add ARM CCA support to the qemu driver for aarch64 systems.
14+
15+
[XML example]
16+
<domain>
17+
...
18+
<launchsecurity type='cca'>
19+
<measurement-algo>sha256</measurement-algo>
20+
</launchsecurity>
21+
...
22+
</domain>
23+
24+
Signed-off-by: Kazuhiro Abe <fj1078ii@aa.jp.fujitsu.com>
25+
Signed-off-by: rpm-build <rpm-build>
26+
Signed-off-by: WangYuli <wangyuli@aosc.io>
27+
---
28+
docs/formatdomain.rst | 43 ++++++++++++++++++++++++++++++++++
29+
src/conf/domain_capabilities.h | 6 +++++
30+
src/conf/domain_conf.c | 25 ++++++++++++++++++++
31+
src/conf/domain_conf.h | 9 +++++++
32+
src/conf/virconftypes.h | 2 ++
33+
src/qemu/qemu_capabilities.c | 6 +++++
34+
src/qemu/qemu_capabilities.h | 3 +++
35+
src/qemu/qemu_command.c | 28 ++++++++++++++++++++++
36+
src/qemu/qemu_firmware.c | 1 +
37+
src/qemu/qemu_namespace.c | 2 ++
38+
src/qemu/qemu_process.c | 4 ++++
39+
src/qemu/qemu_validate.c | 4 ++++
40+
12 files changed, 133 insertions(+)
41+
42+
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
43+
index 47d3e212..3b169a01 100644
44+
--- a/docs/formatdomain.rst
45+
+++ b/docs/formatdomain.rst
46+
@@ -9028,6 +9028,49 @@ The ``<launchSecurity/>`` element then accepts the following child elements:
47+
blob to provide to the guest, as documented for the 'HOST_DATA' parameter of
48+
the SNP_LAUNCH_FINISH command in the SEV-SNP firmware ABI.
49+
50+
+The contents of the ``<launchSecurity type='cca'>`` element is used to create
51+
+RealmVM using the Arm CCA feature (Confidential Compute Architecture).
52+
+CCA :since:`Since 11.0.0` enhances the virtualization capabilities of the
53+
+platform by separating the management of resources from access to those resources.
54+
+This is achieved by extending the TrustZone of Cortex-A's Normal and Secure
55+
+world concepts and adding the Realm world and the underlying Root world.
56+
+The Secure Monitor runs in the root world and manages the transition between
57+
+these security states. For more information see the Learn the architecture -
58+
+Arm Confidential Compute Architecture software stack:
59+
+`<https://developer.arm.com/documentation/den0127/latest>`__
60+
+
61+
+::
62+
+
63+
+ <domain>
64+
+ ...
65+
+ <launchSecurity type='cca' measurement-log='yes'>
66+
+ <measurement-algo>sha256</measurement-algo>
67+
+ <personalization-value>...</personalization-value>
68+
+ </launchSecurity>
69+
+ ...
70+
+ </domain>
71+
+
72+
+The ``<launchSecurity/>`` element accepts the following attributes:
73+
+
74+
+``measurement-algo``
75+
+ The optional ``measurement-algo`` element determines algorithm used to
76+
+ describe blob hashes.
77+
+
78+
+``personalization-value``
79+
+ The optional ``personalization-value`` element is used to configure
80+
+ the Realm Personalization Value (RPV). The Realm Personalization
81+
+ Value (RPV) is provided by the user to distinguish Realms that have
82+
+ the same initial measurement. The personalization-value for libvirt
83+
+ must be an 88-character string representing the Base64 encoding of
84+
+ the 64-byte hexadecimal value defined in the RMM specification.
85+
+ Ensure that you encode the 64-byte hex value from the RMM specification
86+
+ using Base64 before providing it to libvirt.
87+
+
88+
+``measurement-log``
89+
+ The optional ``measurement-log`` element provides a way to create
90+
+ an event log in the format defined by the Trusted Computing Group
91+
+ for TPM2.
92+
+
93+
94+
Example configs
95+
===============
96+
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
97+
index 2a4596ac..01076c32 100644
98+
--- a/src/conf/domain_capabilities.h
99+
+++ b/src/conf/domain_capabilities.h
100+
@@ -239,6 +239,12 @@ struct _virSGXCapability {
101+
virSGXSection *sgxSections;
102+
};
103+
104+
+typedef struct _virCCACapability virCCACapability;
105+
+struct _virCCACapability {
106+
+ size_t nCcaMeasurementAlgo;
107+
+ char **ccaMeasurementAlgo;
108+
+};
109+
+
110+
STATIC_ASSERT_ENUM(VIR_DOMAIN_CRYPTO_MODEL_LAST);
111+
STATIC_ASSERT_ENUM(VIR_DOMAIN_CRYPTO_TYPE_LAST);
112+
STATIC_ASSERT_ENUM(VIR_DOMAIN_CRYPTO_BACKEND_LAST);
113+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
114+
index cc2c606b..b90b766d 100644
115+
--- a/src/conf/domain_conf.c
116+
+++ b/src/conf/domain_conf.c
117+
@@ -1515,6 +1515,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
118+
"sev",
119+
"sev-snp",
120+
"s390-pv",
121+
+ "cca",
122+
);
123+
124+
VIR_ENUM_IMPL(virDomainPstoreBackend,
125+
@@ -3868,6 +3869,10 @@ virDomainSecDefFree(virDomainSecDef *def)
126+
g_free(def->data.sev_snp.id_auth);
127+
g_free(def->data.sev_snp.host_data);
128+
break;
129+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
130+
+ g_free(def->data.cca.measurement_algo);
131+
+ g_free(def->data.cca.personalization_value);
132+
+ break;
133+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
134+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
135+
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
136+
@@ -13791,6 +13796,21 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def,
137+
}
138+
139+
140+
+static int
141+
+virDomainCCADefParseXML(virDomainCCADef *def,
142+
+ xmlXPathContextPtr ctxt)
143+
+{
144+
+ def->measurement_algo = virXPathString("string(./measurement-algo)", ctxt);
145+
+ def->personalization_value = virXPathString("string(./personalization-value)", ctxt);
146+
+
147+
+ if (virXMLPropTristateBool(ctxt->node, "measurement-log", VIR_XML_PROP_NONE,
148+
+ &def->measurement_log) < 0)
149+
+ return -1;
150+
+
151+
+ return 0;
152+
+}
153+
+
154+
+
155+
static virDomainSecDef *
156+
virDomainSecDefParseXML(xmlNodePtr lsecNode,
157+
xmlXPathContextPtr ctxt)
158+
@@ -13816,6 +13836,10 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode,
159+
break;
160+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
161+
break;
162+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
163+
+ if (virDomainCCADefParseXML(&sec->data.cca, ctxt) < 0)
164+
+ return NULL;
165+
+ break;
166+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
167+
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
168+
default:
169+
@@ -26977,6 +27001,7 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec)
170+
break;
171+
172+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
173+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
174+
break;
175+
176+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
177+
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
178+
index 439429db..f16ffa0c 100644
179+
--- a/src/conf/domain_conf.h
180+
+++ b/src/conf/domain_conf.h
181+
@@ -2870,6 +2870,7 @@ typedef enum {
182+
VIR_DOMAIN_LAUNCH_SECURITY_SEV,
183+
VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP,
184+
VIR_DOMAIN_LAUNCH_SECURITY_PV,
185+
+ VIR_DOMAIN_LAUNCH_SECURITY_CCA,
186+
187+
VIR_DOMAIN_LAUNCH_SECURITY_LAST,
188+
} virDomainLaunchSecurity;
189+
@@ -2907,11 +2908,19 @@ struct _virDomainSEVSNPDef {
190+
};
191+
192+
193+
+struct _virDomainCCADef {
194+
+ char *measurement_algo;
195+
+ char *personalization_value;
196+
+ virTristateBool measurement_log;
197+
+};
198+
+
199+
+
200+
struct _virDomainSecDef {
201+
virDomainLaunchSecurity sectype;
202+
union {
203+
virDomainSEVDef sev;
204+
virDomainSEVSNPDef sev_snp;
205+
+ virDomainCCADef cca;
206+
} data;
207+
};
208+
209+
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
210+
index f18ebcca..76218f51 100644
211+
--- a/src/conf/virconftypes.h
212+
+++ b/src/conf/virconftypes.h
213+
@@ -216,6 +216,8 @@ typedef struct _virDomainSEVDef virDomainSEVDef;
214+
215+
typedef struct _virDomainSEVSNPDef virDomainSEVSNPDef;
216+
217+
+typedef struct _virDomainCCADef virDomainCCADef;
218+
+
219+
typedef struct _virDomainSecDef virDomainSecDef;
220+
221+
typedef struct _virDomainShmemDef virDomainShmemDef;
222+
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
223+
index 0da12800..d3bd015e 100644
224+
--- a/src/qemu/qemu_capabilities.c
225+
+++ b/src/qemu/qemu_capabilities.c
226+
@@ -715,6 +715,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
227+
"acpi-erst", /* QEMU_CAPS_DEVICE_ACPI_ERST */
228+
"intel-iommu.dma-translation", /* QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION */
229+
"machine-i8042-opt", /* QEMU_CAPS_MACHINE_I8042_OPT */
230+
+
231+
+ /* 465 */
232+
+ "rme-guest", /* QEMU_CAPS_CCA_GUEST */
233+
);
234+
235+
236+
@@ -800,6 +803,8 @@ struct _virQEMUCaps {
237+
238+
virSGXCapability *sgxCapabilities;
239+
240+
+ virCCACapability *ccaCapabilities;
241+
+
242+
virDomainCapsFeatureHyperv *hypervCapabilities;
243+
244+
/* Capabilities which may differ depending on the accelerator. */
245+
@@ -1406,6 +1411,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
246+
{ "virtio-sound-device", QEMU_CAPS_DEVICE_VIRTIO_SOUND },
247+
{ "sev-snp-guest", QEMU_CAPS_SEV_SNP_GUEST },
248+
{ "acpi-erst", QEMU_CAPS_DEVICE_ACPI_ERST },
249+
+ { "rme-guest", QEMU_CAPS_CCA_GUEST },
250+
};
251+
252+
253+
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
254+
index 5036d49a..1eb94f41 100644
255+
--- a/src/qemu/qemu_capabilities.h
256+
+++ b/src/qemu/qemu_capabilities.h
257+
@@ -695,6 +695,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
258+
QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION, /* intel-iommu.dma-translation */
259+
QEMU_CAPS_MACHINE_I8042_OPT, /* -machine xxx,i8042=on/off; use virQEMUCapsSupportsI8042Toggle() to query this capability */
260+
261+
+ /* 465 */
262+
+ QEMU_CAPS_CCA_GUEST, /* -object rme-guest */
263+
+
264+
QEMU_CAPS_LAST /* this must always be the last item */
265+
} virQEMUCapsFlags;
266+
267+
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
268+
index 8d4016a5..dee0b738 100644
269+
--- a/src/qemu/qemu_command.c
270+
+++ b/src/qemu/qemu_command.c
271+
@@ -7085,6 +7085,9 @@ qemuBuildMachineCommandLine(virCommand *cmd,
272+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
273+
virBufferAddLit(&buf, ",confidential-guest-support=lsec0");
274+
break;
275+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
276+
+ virBufferAddLit(&buf, ",confidential-guest-support=rme0");
277+
+ break;
278+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
279+
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
280+
virReportEnumRangeError(virDomainLaunchSecurity, def->sec->sectype);
281+
@@ -9849,6 +9852,29 @@ qemuBuildPVCommandLine(virDomainObj *vm, virCommand *cmd)
282+
}
283+
284+
285+
+static int
286+
+qemuBuildCCACommandLine(virCommand *cmd, virDomainCCADef *cca, qemuDomainObjPrivate *priv)
287+
+{
288+
+ g_autoptr(virJSONValue) props = NULL;
289+
+
290+
+ VIR_DEBUG("measurement_algorithm=%s personalization_value=%s measurement_log=%d",
291+
+ cca->measurement_algo, cca->personalization_value,
292+
+ cca->measurement_log);
293+
+
294+
+ if (qemuMonitorCreateObjectProps(&props, "rme-guest", "rme0",
295+
+ "S:measurement-algorithm", cca->measurement_algo,
296+
+ "S:personalization-value", cca->personalization_value,
297+
+ "T:measurement-log", cca->measurement_log,
298+
+ NULL) < 0)
299+
+ return -1;
300+
+
301+
+ if (qemuBuildObjectCommandlineFromJSON(cmd, props, priv->qemuCaps) < 0)
302+
+ return -1;
303+
+
304+
+ return 0;
305+
+}
306+
+
307+
+
308+
static int
309+
qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
310+
virDomainSecDef *sec)
311+
@@ -9866,6 +9892,8 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
312+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
313+
return qemuBuildPVCommandLine(vm, cmd);
314+
break;
315+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
316+
+ return qemuBuildCCACommandLine(cmd, &sec->data.cca, vm->privateData);
317+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
318+
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
319+
virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
320+
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
321+
index 914f8596..9bf57164 100644
322+
--- a/src/qemu/qemu_firmware.c
323+
+++ b/src/qemu/qemu_firmware.c
324+
@@ -1371,6 +1371,7 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
325+
}
326+
break;
327+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
328+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
329+
break;
330+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
331+
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
332+
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
333+
index bbe3d5a1..69295306 100644
334+
--- a/src/qemu/qemu_namespace.c
335+
+++ b/src/qemu/qemu_namespace.c
336+
@@ -660,6 +660,8 @@ qemuDomainSetupLaunchSecurity(virDomainObj *vm,
337+
338+
VIR_DEBUG("Set up launch security for SEV");
339+
break;
340+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
341+
+ break;
342+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
343+
break;
344+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
345+
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
346+
index d29839c5..0f264f53 100644
347+
--- a/src/qemu/qemu_process.c
348+
+++ b/src/qemu/qemu_process.c
349+
@@ -6757,6 +6757,8 @@ qemuProcessPrepareDomain(virQEMUDriver *driver,
350+
if (qemuProcessUpdateSEVInfo(vm) < 0)
351+
return -1;
352+
break;
353+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
354+
+ break;
355+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
356+
break;
357+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
358+
@@ -6839,6 +6841,8 @@ qemuProcessPrepareLaunchSecurityGuestInput(virDomainObj *vm)
359+
return qemuProcessPrepareSEVGuestInput(vm);
360+
case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP:
361+
break;
362+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
363+
+ return 0;
364+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
365+
return 0;
366+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
367+
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
368+
index 3c40f76c..b18573d5 100644
369+
--- a/src/qemu/qemu_validate.c
370+
+++ b/src/qemu/qemu_validate.c
371+
@@ -1365,6 +1365,10 @@ qemuValidateDomainDef(const virDomainDef *def,
372+
return -1;
373+
}
374+
break;
375+
+
376+
+ case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
377+
+ break;
378+
+
379+
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
380+
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
381+
virReportEnumRangeError(virDomainLaunchSecurity, def->sec->sectype);
382+
--
383+
2.51.0
384+

0 commit comments

Comments
 (0)