Commit 43a21a0f authored by Fuad Tabba's avatar Fuad Tabba Committed by Marc Zyngier
Browse files

KVM: arm64: Include VM type when checking VM capabilities in pKVM



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: default avatarFuad Tabba <tabba@google.com>
Link: https://patch.msgid.link/20251211104710.151771-6-tabba@google.com


Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent c273feee
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -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);
	}
}

+2 −2
Original line number Diff line number Diff line
@@ -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) {
+5 −5
Original line number Diff line number Diff line
@@ -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);
	}