[PATCH v16 44/45] KVM: arm64: CCA: Require ICH_HCR_EL2.TDIR for realms

Steven Price <[email protected]> Mon, 3 Aug 2026 14:44:00 +0100
Newsgroups dev.linux.lists.linux-coco,dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.kvm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
KVM advertises realm support when the RMM is available, and allows
userspace to create a VM with KVM_VM_TYPE_ARM_REALM on that basis.

On CPUs that lack ICH_HCR_EL2.TDIR, KVM uses ICH_HCR_EL2.TC for
normal guests so that ICC_DIR_EL1 is still trapped via the common GICv3
CPU interface trap. Realms cannot rely on the normal hyp-side trap
handling for that fallback, so advertising RMI support on such systems
lets userspace create a realm that cannot safely run.

Require the finalized ARM64_HAS_ICH_HCR_EL2_TDIR capability when
reporting KVM_CAP_ARM_RMI and when accepting KVM_VM_TYPE_ARM_REALM.
This leaves normal VM creation unchanged on systems that need the TC
workaround.

Signed-off-by: Steven Price <[email protected]>
---
New patch for v16
---
 arch/arm64/kvm/arm.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index fd4e13ff17cf..7edc572dd8ab 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -125,6 +125,12 @@ static bool vgic_present, kvm_arm_initialised;
 
 static DEFINE_PER_CPU(unsigned char, kvm_hyp_initialized);
 
+static bool kvm_arm_rmi_supported(void)
+{
+	return static_key_enabled(&kvm_rmi_is_available) &&
+	       cpus_have_final_cap(ARM64_HAS_ICH_HCR_EL2_TDIR);
+}
+
 bool is_kvm_arm_initialised(void)
 {
 	return kvm_arm_initialised;
@@ -256,7 +262,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 		return -EINVAL;
 
 	if (type & KVM_VM_TYPE_ARM_REALM) {
-		if (!static_branch_unlikely(&kvm_rmi_is_available))
+		if (!kvm_arm_rmi_supported())
 			return -EINVAL;
 		kvm_set_realm_state(kvm, REALM_STATE_NONE);
 		kvm->arch.is_realm = true;
@@ -537,7 +543,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 			r = kvm_supports_cacheable_pfnmap();
 		break;
 	case KVM_CAP_ARM_RMI:
-		r = static_key_enabled(&kvm_rmi_is_available);
+		r = kvm_arm_rmi_supported();
 		break;
 
 	default:
-- 
2.43.0