]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: arm64: Include VM type when checking VM capabilities in pKVM
authorFuad Tabba <tabba@google.com>
Thu, 11 Dec 2025 10:47:05 +0000 (10:47 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 15 Jan 2026 15:43:15 +0000 (15:43 +0000)
Certain features and capabilities are restricted in protected mode. Most
of these features are restricted only for protected VMs, but some
are restricted for ALL VMs in protected mode.

Extend the pKVM capability check to pass the VM (kvm), and use that when
determining supported features.

Signed-off-by: Fuad Tabba <tabba@google.com>
Link: https://patch.msgid.link/20251211104710.151771-6-tabba@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_pkvm.h
arch/arm64/kvm/arm.c
arch/arm64/kvm/hyp/nvhe/pkvm.c

index 0aecd4ac5f45da75ff57cda11f5e8fa600a14457..cccfff96f0629a52114a4149b3aa2e55b701e09d 100644 (file)
@@ -23,10 +23,12 @@ void pkvm_destroy_hyp_vm(struct kvm *kvm);
 int pkvm_create_hyp_vcpu(struct kvm_vcpu *vcpu);
 
 /*
- * This functions as an allow-list of protected VM capabilities.
- * Features not explicitly allowed by this function are denied.
+ * Check whether the specific capability is allowed in pKVM.
+ *
+ * Certain features are allowed only for non-protected VMs in pKVM, which is why
+ * this takes the VM (kvm) as a parameter.
  */
-static inline bool kvm_pvm_ext_allowed(long ext)
+static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
 {
        switch (ext) {
        case KVM_CAP_IRQCHIP:
@@ -43,7 +45,7 @@ static inline bool kvm_pvm_ext_allowed(long ext)
        case KVM_CAP_ARM_PTRAUTH_GENERIC:
                return true;
        default:
-               return false;
+               return !kvm || !kvm_vm_is_protected(kvm);
        }
 }
 
index 4f80da0c0d1de89abc0c0dfd90c8adf318a8c9be..e906ad414e7289ee2f4cdbe5c194f0315438c7f1 100644 (file)
@@ -87,7 +87,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
        if (cap->flags)
                return -EINVAL;
 
-       if (kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(cap->cap))
+       if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, cap->cap))
                return -EINVAL;
 
        switch (cap->cap) {
@@ -303,7 +303,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 {
        int r;
 
-       if (kvm && kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(ext))
+       if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, ext))
                return 0;
 
        switch (ext) {
index d99137dddb1f530f3cf8ce4497003c9b3c919fc2..191d6f51611347f52a3ae2503694acfa342339a6 100644 (file)
@@ -354,23 +354,23 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
                return;
        }
 
-       if (kvm_pvm_ext_allowed(KVM_CAP_ARM_MTE))
+       if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_MTE))
                kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_MTE_ENABLED);
 
        bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
 
        set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
 
-       if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PMU_V3))
+       if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PMU_V3))
                set_bit(KVM_ARM_VCPU_PMU_V3, allowed_features);
 
-       if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_ADDRESS))
+       if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PTRAUTH_ADDRESS))
                set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
 
-       if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_GENERIC))
+       if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PTRAUTH_GENERIC))
                set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
 
-       if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE)) {
+       if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_SVE)) {
                set_bit(KVM_ARM_VCPU_SVE, allowed_features);
                kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_GUEST_HAS_SVE);
        }