[PATCH v23 14/14] KVM: arm64: Prevent unsupported vcpu features for VM types
From: Suzuki K Poulose
Date: Wed Oct 07 2026 - 03:40:08 EST
Prevent unsupported VCPU features for the protected VCPUs. Realms and pVMs
not support 32bit EL1 or NV yet. pKVM doesn't rely on the host vcpu
features for protected VMs and hand picks features while hyp_vcpu is
initialised. Block the features early in the vcpu init if we detect
incompatible features.
Signed-off-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
---
Changes since v22:
- Start off with the base features supported per VM type
---
arch/arm64/include/asm/kvm_host.h | 7 +++++++
arch/arm64/kvm/arm.c | 11 ++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 4d0e6bd2009ac..97089c81d6428 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -42,6 +42,13 @@
#define KVM_VCPU_MAX_FEATURES 10
#define KVM_VCPU_VALID_FEATURES (BIT(KVM_VCPU_MAX_FEATURES) - 1)
+/* As dictated by kvm_pkvm_ext_allowed() */
+#define KVM_PROTECTED_VCPU_VALID_FEATURES \
+ (BIT(KVM_ARM_VCPU_POWER_OFF) | \
+ BIT(KVM_ARM_VCPU_PSCI_0_2) | \
+ BIT(KVM_ARM_VCPU_PTRAUTH_ADDRESS) | \
+ BIT(KVM_ARM_VCPU_PTRAUTH_GENERIC))
+
#define KVM_REQ_SLEEP \
KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index f31d31fa27ad9..a53f2b2799cf8 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1668,9 +1668,14 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
return -EINVAL;
}
-static unsigned long system_supported_vcpu_features(void)
+static unsigned long system_supported_vcpu_features(struct kvm_vcpu *vcpu)
{
- unsigned long features = KVM_VCPU_VALID_FEATURES;
+ unsigned long features;
+
+ if (vcpu->kvm->arch.vm_flavor == VM_PROTECTED_PKVM)
+ features = KVM_PROTECTED_VCPU_VALID_FEATURES;
+ else
+ features = KVM_VCPU_VALID_FEATURES;
if (!cpus_have_final_cap(ARM64_HAS_32BIT_EL1))
clear_bit(KVM_ARM_VCPU_EL1_32BIT, &features);
@@ -1708,7 +1713,7 @@ static int kvm_vcpu_init_check_features(struct kvm_vcpu *vcpu,
return -ENOENT;
}
- if (features & ~system_supported_vcpu_features())
+ if (features & ~system_supported_vcpu_features(vcpu))
return -EINVAL;
/*
--
2.43.0