[PATCH v16 13/45] KVM: arm64: CCA: Define the user ABI

From: Steven Price

Date: Mon Aug 03 2026 - 11:21:04 EST


There is one CAP (KVM_CAP_ARM_RMI) which identifies the presence of CCA,
and one ioctl. The ioctl (KVM_ARM_RMI_POPULATE) is used to populate
memory during creation of the realm as this requires the RMM to copy
data from an unprotected address to the protected memory - CCA does not
support shared <-> private memory conversion where the memory contents
is preserved as this is incompatible with memory encryption.

Signed-off-by: Steven Price <steven.price@xxxxxxx>
---
Changes since v15:
* Expand KVM_ARM_RMI_POPULATE documentation to be explicit that
in-place shared-to-private conversion isn't supported.
Changes since v13:
* KVM_ARM_VCPU_RMI_PSCI_COMPLETE removed.
* KVM_ARM_RMI_POPULATE documentation updated to reflect that the
structure is written by the kernel.
* CAP number bumped.
Changes since v12:
* Change KVM_ARM_RMI_POPULATE to update the structure with the amount
that has been progressed rather than return the number of bytes
populated.
* Describe the flag KVM_ARM_RMI_POPULATE_FLAGS_MEASURE.
* CAP number is bumped.
* NOTE: The PSCI ioctl may be removed in a future spec release.
Changes since v11:
* Completely reworked to be more implicit. Rather than having explicit
CAP operations to progress the realm construction these operations
are done when needed (on populating and on first vCPU run).
* Populate and PSCI complete are promoted to proper ioctls.
Changes since v10:
* Rename symbols from RME to RMI.
Changes since v9:
* Improvements to documentation.
* Bump the magic number for KVM_CAP_ARM_RME to avoid conflicts.
Changes since v8:
* Minor improvements to documentation following review.
* Bump the magic numbers to avoid conflicts.
Changes since v7:
* Add documentation of new ioctls
* Bump the magic numbers to avoid conflicts
Changes since v6:
* Rename some of the symbols to make their usage clearer and avoid
repetition.
Changes from v5:
* Actually expose the new VCPU capability (KVM_ARM_VCPU_REC) by bumping
KVM_VCPU_MAX_FEATURES - note this also exposes KVM_ARM_VCPU_HAS_EL2!
---
Documentation/virt/kvm/api.rst | 47 ++++++++++++++++++++++++++++++++++
include/uapi/linux/kvm.h | 13 ++++++++++
2 files changed, 60 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 1de6fd5fc88c..ce588c05b26a 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -6642,6 +6642,44 @@ if the guest_memfd memory was pinned in IOMMU page tables.

See also: :ref: `KVM_SET_MEMORY_ATTRIBUTES`.

+4.146 KVM_ARM_RMI_POPULATE
+--------------------------
+
+:Capability: KVM_CAP_ARM_RMI
+:Architectures: arm64
+:Type: vm ioctl
+:Parameters: struct kvm_arm_rmi_populate (in/out)
+:Returns: 0 on success, < 0 on error
+
+::
+
+ struct kvm_arm_rmi_populate {
+ __u64 base;
+ __u64 size;
+ __u64 source_uaddr;
+ __u32 flags;
+ __u32 reserved;
+ };
+
+Populate the guest address range described by `base` and `size` with data from
+the userspace buffer at `source_uaddr`. The guest_memfd range backing the
+memory must have `KVM_MEMORY_ATTRIBUTE_PRIVATE` set.
+
+Arm CCA cannot perform an in-place shared-to-private conversion while
+preserving memory contents. Therefore, `source_uaddr` must be a valid,
+page-aligned userspace pointer. The operation uses `RMI_RTT_DATA_MAP_INIT`,
+which also sets the region to `RIPAS_RAM`.
+
+This is only valid before any VCPUs have been run. The ioctl might not populate
+the entire region and in this case the kernel updates the fields `base`, `size`
+and `source_uaddr`. User space may have to repeatedly call it until `size` is 0
+to populate the entire region.
+
+`flags` can be set to `KVM_ARM_RMI_POPULATE_FLAGS_MEASURE` to request that the
+populated data is hashed and added to the guest's Realm Initial Measurement
+(RIM) stored by the RMM. This can then be retrieved by the guest (using the RSI
+interface) to present to an attestation server.
+
.. _kvm_run:

5. The kvm_run structure
@@ -9025,6 +9063,15 @@ enabled, cmma can't be enabled anymore and pfmfi and the storage key
interpretation are disabled. If cmma has already been enabled or the
hpage_2g module parameter is not set to 1, -EINVAL is returned.

+7.48 KVM_CAP_ARM_RMI
+--------------------
+
+:Architectures: arm64
+:Target: VM
+:Parameters: None
+
+This capability indicates that support for CCA realms is available.
+
8. Other capabilities.
======================

diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 129d6f630325..0231ff174a50 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -998,6 +998,7 @@ struct kvm_enable_cap {
#define KVM_CAP_S390_VSIE_ESAMODE 248
#define KVM_CAP_S390_HPAGE_2G 249
#define KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES 250
+#define KVM_CAP_ARM_RMI 251

struct kvm_irq_routing_irqchip {
__u32 irqchip;
@@ -1686,4 +1687,16 @@ struct kvm_pre_fault_memory {
__u64 padding[5];
};

+/* Available with KVM_CAP_ARM_RMI, only for VMs with KVM_VM_TYPE_ARM_REALM */
+#define KVM_ARM_RMI_POPULATE _IOWR(KVMIO, 0xd7, struct kvm_arm_rmi_populate)
+#define KVM_ARM_RMI_POPULATE_FLAGS_MEASURE (1 << 0)
+
+struct kvm_arm_rmi_populate {
+ __u64 base;
+ __u64 size;
+ __u64 source_uaddr;
+ __u32 flags;
+ __u32 reserved;
+};
+
#endif /* __LINUX_KVM_H */
--
2.43.0