public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling
@ 2025-12-11 10:47 Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 1/9] KVM: arm64: Fix Trace Buffer trapping for protected VMs Fuad Tabba
                   ` (9 more replies)
  0 siblings, 10 replies; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

Hi,

This series contains several fixes for guest feature trapping and
enabling in pKVM, as well as a bit of tidying up.

Changes from v6 [1]:
- Fixes to the patch that tracks KVM IOCTLs and their associated KVM
  caps. Move static header data and function definitions to arm.c.
- Introduce a capability KVM_CAP_ARM_BASIC instead of KVM_CAP_CORE,
  since it is ARM-specific and that it only checks basic ARM ioctls.
- Tidying up code and commit messages.
- Based on Linux 6.18

Cheers,
/fuad

[1] https://lore.kernel.org/all/20251118103807.707500-1-tabba@google.com/

Fuad Tabba (9):
  KVM: arm64: Fix Trace Buffer trapping for protected VMs
  KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
  KVM: arm64: Fix MTE flag initialization for protected VMs
  KVM: arm64: Introduce helper to calculate fault IPA offset
  KVM: arm64: Include VM type when checking VM capabilities in pKVM
  KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest in pKVM
  KVM: arm64: Track KVM IOCTLs and their associated KVM caps
  KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
  KVM: arm64: Prevent host from managing timer offsets for protected VMs

 arch/arm64/include/asm/kvm_arm.h         |  2 +
 arch/arm64/include/asm/kvm_host.h        |  2 +
 arch/arm64/include/asm/kvm_pkvm.h        | 33 ++++++++++++++--
 arch/arm64/kvm/arch_timer.c              | 18 ++++++---
 arch/arm64/kvm/arm.c                     | 49 +++++++++++++++++++++++-
 arch/arm64/kvm/hyp/nvhe/pkvm.c           | 18 ++++-----
 arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c |  2 +-
 arch/arm64/kvm/inject_fault.c            |  2 +-
 arch/arm64/kvm/mmu.c                     |  4 +-
 include/uapi/linux/kvm.h                 |  1 +
 10 files changed, 107 insertions(+), 24 deletions(-)


base-commit: 7d0a66e4bb9081d75c82ec4957c50034cb0ea449
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v6 1/9] KVM: arm64: Fix Trace Buffer trapping for protected VMs
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
@ 2025-12-11 10:47 ` Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 2/9] KVM: arm64: Fix Trace Buffer trap polarity " Fuad Tabba
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

For protected VMs in pKVM, the hypervisor should trap accesses to trace
buffer system registers if Trace Buffer isn't supported by the VM.
However, the current code only traps if Trace Buffer External Mode isn't
supported.

Fix this by checking for FEAT_TRBE (Trace Buffer) rather than
FEAT_TRBE_EXT.

Fixes: 9d5261269098 ("KVM: arm64: Trap external trace for protected VMs")
Reported-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 43bde061b65d..8d06a246dfd1 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -117,7 +117,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
 		val |= MDCR_EL2_TTRF;
 
-	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, ExtTrcBuff, IMP))
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
 		val |= MDCR_EL2_E2TB_MASK;
 
 	/* Trap Debug Communications Channel registers */
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 1/9] KVM: arm64: Fix Trace Buffer trapping for protected VMs Fuad Tabba
@ 2025-12-11 10:47 ` Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 3/9] KVM: arm64: Fix MTE flag initialization " Fuad Tabba
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
register accesses. These accesses are trapped to EL2 when the bits are
clear.

The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
had the polarity inverted. When a guest did not support the Trace Buffer
feature, the code was setting E2TB. This incorrectly disabled the trap,
potentially allowing a protected guest to access registers for a feature
it was not given.

Fix this by inverting the operation.

Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 8d06a246dfd1..f6f8996c4f97 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 		val |= MDCR_EL2_TTRF;
 
 	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
-		val |= MDCR_EL2_E2TB_MASK;
+		val &= ~MDCR_EL2_E2TB_MASK;
 
 	/* Trap Debug Communications Channel registers */
 	if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, FGT, IMP))
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 3/9] KVM: arm64: Fix MTE flag initialization for protected VMs
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 1/9] KVM: arm64: Fix Trace Buffer trapping for protected VMs Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 2/9] KVM: arm64: Fix Trace Buffer trap polarity " Fuad Tabba
@ 2025-12-11 10:47 ` Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 4/9] KVM: arm64: Introduce helper to calculate fault IPA offset Fuad Tabba
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

The function pkvm_init_features_from_host() initializes guest
features, propagating them from the host. The logic to propagate
KVM_ARCH_FLAG_MTE_ENABLED (Memory Tagging Extension)
has a couple of issues.

First, the check was in the common path, before the divergence for
protected and non-protected VMs. For non-protected VMs, this was
unnecessary, as 'kvm->arch.flags' is completely overwritten by
host_arch_flags immediately after, which already contains the MTE flag.
For protected VMs, this was setting the flag even if the feature is not
allowed.

Second, the check was reading 'host_kvm->arch.flags' instead of using
the local 'host_arch_flags', which is read once from the host flags.

Fix these by moving the MTE flag check inside the protected-VM-only
path, checking if the feature is allowed, and changing it to use the
correct host_arch_flags local variable. This ensures non-protected VMs
get the flag via the bulk copy, and protected VMs get it via an explicit
check.

Fixes: b7f345fbc32a ("KVM: arm64: Fix FEAT_MTE in pKVM")
Reviewed-by: Ben Horgan <ben.horgan@arm.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index f6f8996c4f97..16d7bf493c18 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -337,9 +337,6 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 	/* CTR_EL0 is always under host control, even for protected VMs. */
 	hyp_vm->kvm.arch.ctr_el0 = host_kvm->arch.ctr_el0;
 
-	if (test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &host_kvm->arch.flags))
-		set_bit(KVM_ARCH_FLAG_MTE_ENABLED, &kvm->arch.flags);
-
 	/* No restrictions for non-protected VMs. */
 	if (!kvm_vm_is_protected(kvm)) {
 		hyp_vm->kvm.arch.flags = host_arch_flags;
@@ -354,6 +351,9 @@ 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))
+		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);
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 4/9] KVM: arm64: Introduce helper to calculate fault IPA offset
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
                   ` (2 preceding siblings ...)
  2025-12-11 10:47 ` [PATCH v6 3/9] KVM: arm64: Fix MTE flag initialization " Fuad Tabba
@ 2025-12-11 10:47 ` Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM Fuad Tabba
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

This 12-bit FAR fault IPA offset mask is hard-coded as 'GENMASK(11, 0)'
in several places to reconstruct the full fault IPA.

Introduce FAR_TO_FIPA_OFFSET() to calculate this value in a shared
header and replace all open-coded instances to improve readability.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/include/asm/kvm_arm.h         | 2 ++
 arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c | 2 +-
 arch/arm64/kvm/inject_fault.c            | 2 +-
 arch/arm64/kvm/mmu.c                     | 4 ++--
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 1da290aeedce..73abe697bc2d 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -343,6 +343,8 @@
 #define PAR_TO_HPFAR(par)		\
 	(((par) & GENMASK_ULL(52 - 1, 12)) >> 8)
 
+#define FAR_TO_FIPA_OFFSET(far) ((far) & GENMASK_ULL(11, 0))
+
 #define ECN(x) { ESR_ELx_EC_##x, #x }
 
 #define kvm_arm_exception_class \
diff --git a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c
index 78579b31a420..43d7dfa2c517 100644
--- a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c
+++ b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c
@@ -44,7 +44,7 @@ int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu)
 
 	/* Build the full address */
 	fault_ipa  = kvm_vcpu_get_fault_ipa(vcpu);
-	fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
+	fault_ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
 
 	/* If not for GICV, move on */
 	if (fault_ipa <  vgic->vgic_cpu_base ||
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index dfcd66c65517..c9bbce017dee 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -258,7 +258,7 @@ void kvm_inject_size_fault(struct kvm_vcpu *vcpu)
 	unsigned long addr, esr;
 
 	addr  = kvm_vcpu_get_fault_ipa(vcpu);
-	addr |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
+	addr |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
 
 	__kvm_inject_sea(vcpu, kvm_vcpu_trap_is_iabt(vcpu), addr);
 
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 7cc964af8d30..5b159cf0d203 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1959,7 +1959,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 
 		/* Falls between the IPA range and the PARange? */
 		if (fault_ipa >= BIT_ULL(VTCR_EL2_IPA(vcpu->arch.hw_mmu->vtcr))) {
-			fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
+			fault_ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
 
 			return kvm_inject_sea(vcpu, is_iabt, fault_ipa);
 		}
@@ -2059,7 +2059,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		 * faulting VA. This is always 12 bits, irrespective
 		 * of the page size.
 		 */
-		ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
+		ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
 		ret = io_mem_abort(vcpu, ipa);
 		goto out_unlock;
 	}
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
                   ` (3 preceding siblings ...)
  2025-12-11 10:47 ` [PATCH v6 4/9] KVM: arm64: Introduce helper to calculate fault IPA offset Fuad Tabba
@ 2025-12-11 10:47 ` Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 6/9] KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest " Fuad Tabba
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

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>
---
 arch/arm64/include/asm/kvm_pkvm.h | 10 ++++++----
 arch/arm64/kvm/arm.c              |  4 ++--
 arch/arm64/kvm/hyp/nvhe/pkvm.c    | 10 +++++-----
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 08be89c95466..7195be508d99 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -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);
 	}
 }
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 052bf0d4d0b0..e4936cb9c8c3 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -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) {
@@ -299,7 +299,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) {
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 16d7bf493c18..581dec4b8271 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -351,23 +351,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);
 	}
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 6/9] KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest in pKVM
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
                   ` (4 preceding siblings ...)
  2025-12-11 10:47 ` [PATCH v6 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM Fuad Tabba
@ 2025-12-11 10:47 ` Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 7/9] KVM: arm64: Track KVM IOCTLs and their associated KVM caps Fuad Tabba
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

Supporting MTE in pKVM introduces significant complexity to the
hypervisor at EL2, even for non-protected VMs, since it would require
EL2 to handle tag management.

For now, do not allow KVM_CAP_ARM_MTE for any VM type in protected mode.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/include/asm/kvm_pkvm.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 7195be508d99..5b564576160d 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -44,6 +44,8 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_PTRAUTH_ADDRESS:
 	case KVM_CAP_ARM_PTRAUTH_GENERIC:
 		return true;
+	case KVM_CAP_ARM_MTE:
+		return false;
 	default:
 		return !kvm || !kvm_vm_is_protected(kvm);
 	}
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 7/9] KVM: arm64: Track KVM IOCTLs and their associated KVM caps
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
                   ` (5 preceding siblings ...)
  2025-12-11 10:47 ` [PATCH v6 6/9] KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest " Fuad Tabba
@ 2025-12-11 10:47 ` Fuad Tabba
  2025-12-11 10:47 ` [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM Fuad Tabba
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

Track KVM IOCTLs (VM IOCTLs for now), and the associated KVM capability
that enables that IOCTL. Add a function that performs the lookup.

This will be used by CoCo VM Hypervisors (e.g., pKVM) to determine
whether a particular KVM IOCTL is allowed for its VMs.

Suggested-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/include/asm/kvm_host.h |  2 ++
 arch/arm64/kvm/arm.c              | 42 +++++++++++++++++++++++++++++++
 include/uapi/linux/kvm.h          |  1 +
 3 files changed, 45 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 64302c438355..9def5e1f536c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1652,4 +1652,6 @@ static __always_inline enum fgt_group_id __fgt_reg_to_group_id(enum vcpu_sysreg
 		p;							\
 	})
 
+long kvm_get_cap_for_kvm_ioctl(unsigned int ioctl, long *ext);
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e4936cb9c8c3..1bbba79e2686 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -58,6 +58,48 @@ enum kvm_wfx_trap_policy {
 static enum kvm_wfx_trap_policy kvm_wfi_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;
 static enum kvm_wfx_trap_policy kvm_wfe_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;
 
+/*
+ * Tracks KVM IOCTLs and their associated KVM capabilities.
+ */
+struct kvm_ioctl_cap_map {
+	unsigned int ioctl;
+	long ext;
+};
+
+/*
+ * Sorted by ioctl to allow for potential binary search,
+ * though linear scan is sufficient for this size.
+ */
+static const struct kvm_ioctl_cap_map vm_ioctl_caps[] = {
+	{ KVM_CREATE_IRQCHIP, KVM_CAP_IRQCHIP },
+	{ KVM_ARM_SET_DEVICE_ADDR, KVM_CAP_ARM_SET_DEVICE_ADDR },
+	{ KVM_ARM_MTE_COPY_TAGS, KVM_CAP_ARM_MTE },
+	{ KVM_SET_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL },
+	{ KVM_GET_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL },
+	{ KVM_HAS_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL },
+	{ KVM_ARM_SET_COUNTER_OFFSET, KVM_CAP_COUNTER_OFFSET },
+	{ KVM_ARM_GET_REG_WRITABLE_MASKS, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES },
+	{ KVM_ARM_PREFERRED_TARGET, KVM_CAP_ARM_BASIC },
+};
+
+/*
+ * Set *ext to the capability.
+ * Return 0 if found, or -EINVAL if no IOCTL matches.
+ */
+long kvm_get_cap_for_kvm_ioctl(unsigned int ioctl, long *ext)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vm_ioctl_caps); i++) {
+		if (vm_ioctl_caps[i].ioctl == ioctl) {
+			*ext = vm_ioctl_caps[i].ext;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
 DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);
 
 DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_base);
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 52f6000ab020..861733b8f159 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -963,6 +963,7 @@ struct kvm_enable_cap {
 #define KVM_CAP_RISCV_MP_STATE_RESET 242
 #define KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED 243
 #define KVM_CAP_GUEST_MEMFD_FLAGS 244
+#define KVM_CAP_ARM_BASIC 245
 
 struct kvm_irq_routing_irqchip {
 	__u32 irqchip;
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
                   ` (6 preceding siblings ...)
  2025-12-11 10:47 ` [PATCH v6 7/9] KVM: arm64: Track KVM IOCTLs and their associated KVM caps Fuad Tabba
@ 2025-12-11 10:47 ` Fuad Tabba
  2026-01-15 15:03   ` Marc Zyngier
  2025-12-11 10:47 ` [PATCH v6 9/9] KVM: arm64: Prevent host from managing timer offsets for protected VMs Fuad Tabba
  2026-01-15 21:55 ` [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Marc Zyngier
  9 siblings, 1 reply; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

Certain VM IOCTLs are tied to specific VM features. Since pKVM does not
support all features, restrict which IOCTLs are allowed depending on
whether the associated feature is supported.

Use the existing VM capability check as the source of truth to whether
an IOCTL is allowed for a particular VM by mapping the IOCTLs with their
associated capabilities.

Suggested-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/include/asm/kvm_pkvm.h | 21 +++++++++++++++++++++
 arch/arm64/kvm/arm.c              |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 5b564576160d..0fa8c84816fd 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -9,6 +9,7 @@
 #include <linux/arm_ffa.h>
 #include <linux/memblock.h>
 #include <linux/scatterlist.h>
+#include <asm/kvm_host.h>
 #include <asm/kvm_pgtable.h>
 
 /* Maximum number of VMs that can co-exist under pKVM. */
@@ -43,6 +44,7 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_SVE:
 	case KVM_CAP_ARM_PTRAUTH_ADDRESS:
 	case KVM_CAP_ARM_PTRAUTH_GENERIC:
+	case KVM_CAP_ARM_BASIC:
 		return true;
 	case KVM_CAP_ARM_MTE:
 		return false;
@@ -51,6 +53,25 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
 	}
 }
 
+/*
+ * Check whether the KVM VM IOCTL 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_pkvm_ioctl_allowed(struct kvm *kvm, unsigned int ioctl)
+{
+	long ext;
+	int r;
+
+	r = kvm_get_cap_for_kvm_ioctl(ioctl, &ext);
+
+	if (WARN_ON_ONCE(r < 0))
+		return false;
+
+	return kvm_pkvm_ext_allowed(kvm, ext);
+}
+
 extern struct memblock_region kvm_nvhe_sym(hyp_memory)[];
 extern unsigned int kvm_nvhe_sym(hyp_memblock_nr);
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 1bbba79e2686..d9a8745d0bd6 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1921,6 +1921,9 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
 	void __user *argp = (void __user *)arg;
 	struct kvm_device_attr attr;
 
+	if (is_protected_kvm_enabled() && !kvm_pkvm_ioctl_allowed(kvm, ioctl))
+		return -EINVAL;
+
 	switch (ioctl) {
 	case KVM_CREATE_IRQCHIP: {
 		int ret;
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 9/9] KVM: arm64: Prevent host from managing timer offsets for protected VMs
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
                   ` (7 preceding siblings ...)
  2025-12-11 10:47 ` [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM Fuad Tabba
@ 2025-12-11 10:47 ` Fuad Tabba
  2026-01-15 21:55 ` [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Marc Zyngier
  9 siblings, 0 replies; 17+ messages in thread
From: Fuad Tabba @ 2025-12-11 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, vladimir.murzin, tabba

For protected VMs, the guest's timer offset state should not be
controlled by the host and must always run with a virtual counter offset
of 0. The existing timer logic allowed the host to set and manage the
timer counter offsets for protected VMs in certain cases.

Disable all host-side management of timer offsets for protected VMs by
adding checks in the relevant code paths.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/arch_timer.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 3f675875abea..f5407301c8f9 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -1056,10 +1056,14 @@ static void timer_context_init(struct kvm_vcpu *vcpu, int timerid)
 
 	ctxt->timer_id = timerid;
 
-	if (timerid == TIMER_VTIMER)
-		ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset;
-	else
-		ctxt->offset.vm_offset = &kvm->arch.timer_data.poffset;
+	if (!kvm_vm_is_protected(vcpu->kvm)) {
+		if (timerid == TIMER_VTIMER)
+			ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset;
+		else
+			ctxt->offset.vm_offset = &kvm->arch.timer_data.poffset;
+	} else {
+		ctxt->offset.vm_offset = NULL;
+	}
 
 	hrtimer_setup(&ctxt->hrtimer, kvm_hrtimer_expire, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
 
@@ -1083,7 +1087,8 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
 		timer_context_init(vcpu, i);
 
 	/* Synchronize offsets across timers of a VM if not already provided */
-	if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) {
+	if (!vcpu_is_protected(vcpu) &&
+	    !test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) {
 		timer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read());
 		timer_set_offset(vcpu_ptimer(vcpu), 0);
 	}
@@ -1687,6 +1692,9 @@ int kvm_vm_ioctl_set_counter_offset(struct kvm *kvm,
 	if (offset->reserved)
 		return -EINVAL;
 
+	if (kvm_vm_is_protected(kvm))
+		return -EINVAL;
+
 	mutex_lock(&kvm->lock);
 
 	if (!kvm_trylock_all_vcpus(kvm)) {
-- 
2.52.0.223.gf5cc29aaa4-goog



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
  2025-12-11 10:47 ` [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM Fuad Tabba
@ 2026-01-15 15:03   ` Marc Zyngier
  2026-01-15 15:19     ` Fuad Tabba
  0 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2026-01-15 15:03 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin

On Thu, 11 Dec 2025 10:47:08 +0000,
Fuad Tabba <tabba@google.com> wrote:
> 
> Certain VM IOCTLs are tied to specific VM features. Since pKVM does not
> support all features, restrict which IOCTLs are allowed depending on
> whether the associated feature is supported.
> 
> Use the existing VM capability check as the source of truth to whether
> an IOCTL is allowed for a particular VM by mapping the IOCTLs with their
> associated capabilities.
> 
> Suggested-by: Oliver Upton <oupton@kernel.org>
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
>  arch/arm64/include/asm/kvm_pkvm.h | 21 +++++++++++++++++++++
>  arch/arm64/kvm/arm.c              |  3 +++
>  2 files changed, 24 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> index 5b564576160d..0fa8c84816fd 100644
> --- a/arch/arm64/include/asm/kvm_pkvm.h
> +++ b/arch/arm64/include/asm/kvm_pkvm.h
> @@ -9,6 +9,7 @@
>  #include <linux/arm_ffa.h>
>  #include <linux/memblock.h>
>  #include <linux/scatterlist.h>
> +#include <asm/kvm_host.h>
>  #include <asm/kvm_pgtable.h>
>  
>  /* Maximum number of VMs that can co-exist under pKVM. */
> @@ -43,6 +44,7 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
>  	case KVM_CAP_ARM_SVE:
>  	case KVM_CAP_ARM_PTRAUTH_ADDRESS:
>  	case KVM_CAP_ARM_PTRAUTH_GENERIC:
> +	case KVM_CAP_ARM_BASIC:

Can we instead rely on an existing VM capability? I'm not overly keen
exposing something new to userspace (KVM_CAP_ARM_BASIC) for something
that really is KVM's own internal problems.

Looking at the history, a bunch of things have always been present:
KVM_CAP_NR_VCPUS, for example. You could even #define
KVM_CAP_ARM_BASIC to that if you want.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
  2026-01-15 15:03   ` Marc Zyngier
@ 2026-01-15 15:19     ` Fuad Tabba
  2026-01-15 16:05       ` Marc Zyngier
  0 siblings, 1 reply; 17+ messages in thread
From: Fuad Tabba @ 2026-01-15 15:19 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin

Hi Marc,

On Thu, 15 Jan 2026 at 15:03, Marc Zyngier <maz@kernel.org> wrote:
>
> On Thu, 11 Dec 2025 10:47:08 +0000,
> Fuad Tabba <tabba@google.com> wrote:
> >
> > Certain VM IOCTLs are tied to specific VM features. Since pKVM does not
> > support all features, restrict which IOCTLs are allowed depending on
> > whether the associated feature is supported.
> >
> > Use the existing VM capability check as the source of truth to whether
> > an IOCTL is allowed for a particular VM by mapping the IOCTLs with their
> > associated capabilities.
> >
> > Suggested-by: Oliver Upton <oupton@kernel.org>
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> >  arch/arm64/include/asm/kvm_pkvm.h | 21 +++++++++++++++++++++
> >  arch/arm64/kvm/arm.c              |  3 +++
> >  2 files changed, 24 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> > index 5b564576160d..0fa8c84816fd 100644
> > --- a/arch/arm64/include/asm/kvm_pkvm.h
> > +++ b/arch/arm64/include/asm/kvm_pkvm.h
> > @@ -9,6 +9,7 @@
> >  #include <linux/arm_ffa.h>
> >  #include <linux/memblock.h>
> >  #include <linux/scatterlist.h>
> > +#include <asm/kvm_host.h>
> >  #include <asm/kvm_pgtable.h>
> >
> >  /* Maximum number of VMs that can co-exist under pKVM. */
> > @@ -43,6 +44,7 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
> >       case KVM_CAP_ARM_SVE:
> >       case KVM_CAP_ARM_PTRAUTH_ADDRESS:
> >       case KVM_CAP_ARM_PTRAUTH_GENERIC:
> > +     case KVM_CAP_ARM_BASIC:
>
> Can we instead rely on an existing VM capability? I'm not overly keen
> exposing something new to userspace (KVM_CAP_ARM_BASIC) for something
> that really is KVM's own internal problems.
>
> Looking at the history, a bunch of things have always been present:
> KVM_CAP_NR_VCPUS, for example. You could even #define
> KVM_CAP_ARM_BASIC to that if you want.

I wasn't too crazy about that either. I like the idea of defining it
as an alias of KVM_CAP_NR_VCPUS. I'll do that when I respin.

Cheers,
/fuad

> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
  2026-01-15 15:19     ` Fuad Tabba
@ 2026-01-15 16:05       ` Marc Zyngier
  2026-01-15 16:14         ` Fuad Tabba
  0 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2026-01-15 16:05 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin

On Thu, 15 Jan 2026 15:19:48 +0000,
Fuad Tabba <tabba@google.com> wrote:
> 
> Hi Marc,
> 
> On Thu, 15 Jan 2026 at 15:03, Marc Zyngier <maz@kernel.org> wrote:
> >
> > On Thu, 11 Dec 2025 10:47:08 +0000,
> > Fuad Tabba <tabba@google.com> wrote:
> > >
> > > Certain VM IOCTLs are tied to specific VM features. Since pKVM does not
> > > support all features, restrict which IOCTLs are allowed depending on
> > > whether the associated feature is supported.
> > >
> > > Use the existing VM capability check as the source of truth to whether
> > > an IOCTL is allowed for a particular VM by mapping the IOCTLs with their
> > > associated capabilities.
> > >
> > > Suggested-by: Oliver Upton <oupton@kernel.org>
> > > Signed-off-by: Fuad Tabba <tabba@google.com>
> > > ---
> > >  arch/arm64/include/asm/kvm_pkvm.h | 21 +++++++++++++++++++++
> > >  arch/arm64/kvm/arm.c              |  3 +++
> > >  2 files changed, 24 insertions(+)
> > >
> > > diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> > > index 5b564576160d..0fa8c84816fd 100644
> > > --- a/arch/arm64/include/asm/kvm_pkvm.h
> > > +++ b/arch/arm64/include/asm/kvm_pkvm.h
> > > @@ -9,6 +9,7 @@
> > >  #include <linux/arm_ffa.h>
> > >  #include <linux/memblock.h>
> > >  #include <linux/scatterlist.h>
> > > +#include <asm/kvm_host.h>
> > >  #include <asm/kvm_pgtable.h>
> > >
> > >  /* Maximum number of VMs that can co-exist under pKVM. */
> > > @@ -43,6 +44,7 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
> > >       case KVM_CAP_ARM_SVE:
> > >       case KVM_CAP_ARM_PTRAUTH_ADDRESS:
> > >       case KVM_CAP_ARM_PTRAUTH_GENERIC:
> > > +     case KVM_CAP_ARM_BASIC:
> >
> > Can we instead rely on an existing VM capability? I'm not overly keen
> > exposing something new to userspace (KVM_CAP_ARM_BASIC) for something
> > that really is KVM's own internal problems.
> >
> > Looking at the history, a bunch of things have always been present:
> > KVM_CAP_NR_VCPUS, for example. You could even #define
> > KVM_CAP_ARM_BASIC to that if you want.
> 
> I wasn't too crazy about that either. I like the idea of defining it
> as an alias of KVM_CAP_NR_VCPUS. I'll do that when I respin.

I've done something [1]. If that works for you, let me know and I'll
just merge that.

Thanks,

	M.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?h=kvm-arm64/pkvm-features-6.20&id=8823485a697de5c280a7a2632620338722f16663

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
  2026-01-15 16:05       ` Marc Zyngier
@ 2026-01-15 16:14         ` Fuad Tabba
  2026-01-15 18:03           ` Marc Zyngier
  0 siblings, 1 reply; 17+ messages in thread
From: Fuad Tabba @ 2026-01-15 16:14 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin

On Thu, 15 Jan 2026 at 16:05, Marc Zyngier <maz@kernel.org> wrote:
>
> On Thu, 15 Jan 2026 15:19:48 +0000,
> Fuad Tabba <tabba@google.com> wrote:
> >
> > Hi Marc,
> >
> > On Thu, 15 Jan 2026 at 15:03, Marc Zyngier <maz@kernel.org> wrote:
> > >
> > > On Thu, 11 Dec 2025 10:47:08 +0000,
> > > Fuad Tabba <tabba@google.com> wrote:
> > > >
> > > > Certain VM IOCTLs are tied to specific VM features. Since pKVM does not
> > > > support all features, restrict which IOCTLs are allowed depending on
> > > > whether the associated feature is supported.
> > > >
> > > > Use the existing VM capability check as the source of truth to whether
> > > > an IOCTL is allowed for a particular VM by mapping the IOCTLs with their
> > > > associated capabilities.
> > > >
> > > > Suggested-by: Oliver Upton <oupton@kernel.org>
> > > > Signed-off-by: Fuad Tabba <tabba@google.com>
> > > > ---
> > > >  arch/arm64/include/asm/kvm_pkvm.h | 21 +++++++++++++++++++++
> > > >  arch/arm64/kvm/arm.c              |  3 +++
> > > >  2 files changed, 24 insertions(+)
> > > >
> > > > diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> > > > index 5b564576160d..0fa8c84816fd 100644
> > > > --- a/arch/arm64/include/asm/kvm_pkvm.h
> > > > +++ b/arch/arm64/include/asm/kvm_pkvm.h
> > > > @@ -9,6 +9,7 @@
> > > >  #include <linux/arm_ffa.h>
> > > >  #include <linux/memblock.h>
> > > >  #include <linux/scatterlist.h>
> > > > +#include <asm/kvm_host.h>
> > > >  #include <asm/kvm_pgtable.h>
> > > >
> > > >  /* Maximum number of VMs that can co-exist under pKVM. */
> > > > @@ -43,6 +44,7 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
> > > >       case KVM_CAP_ARM_SVE:
> > > >       case KVM_CAP_ARM_PTRAUTH_ADDRESS:
> > > >       case KVM_CAP_ARM_PTRAUTH_GENERIC:
> > > > +     case KVM_CAP_ARM_BASIC:
> > >
> > > Can we instead rely on an existing VM capability? I'm not overly keen
> > > exposing something new to userspace (KVM_CAP_ARM_BASIC) for something
> > > that really is KVM's own internal problems.
> > >
> > > Looking at the history, a bunch of things have always been present:
> > > KVM_CAP_NR_VCPUS, for example. You could even #define
> > > KVM_CAP_ARM_BASIC to that if you want.
> >
> > I wasn't too crazy about that either. I like the idea of defining it
> > as an alias of KVM_CAP_NR_VCPUS. I'll do that when I respin.
>
> I've done something [1]. If that works for you, let me know and I'll
> just merge that.

That works for the previous patch (7/9), which is where you've made
the change. But since the alias is defined in `arm.c` it wouldn't work
in this patch (8/9), because the function kvm_pkvm_ext_allowed() is
defined in  `asm/kvm_pkvm.h`. Defining the alias in `asm/kvm_pkvm.h`
or in `asm/kvm_host.h` should solve this, since both files are visible
in arm.c (and in kvm_pkvm.h in both cases).

Cheers,
/fuad



 > Thanks,
>
>         M.
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?h=kvm-arm64/pkvm-features-6.20&id=8823485a697de5c280a7a2632620338722f16663
>
> --
> Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
  2026-01-15 16:14         ` Fuad Tabba
@ 2026-01-15 18:03           ` Marc Zyngier
  2026-01-15 19:15             ` Fuad Tabba
  0 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2026-01-15 18:03 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin

On Thu, 15 Jan 2026 16:14:39 +0000,
Fuad Tabba <tabba@google.com> wrote:
> 
> On Thu, 15 Jan 2026 at 16:05, Marc Zyngier <maz@kernel.org> wrote:
> >
> > On Thu, 15 Jan 2026 15:19:48 +0000,
> > Fuad Tabba <tabba@google.com> wrote:
> > >
> > > Hi Marc,
> > >
> > > On Thu, 15 Jan 2026 at 15:03, Marc Zyngier <maz@kernel.org> wrote:
> > > >
> > > > On Thu, 11 Dec 2025 10:47:08 +0000,
> > > > Fuad Tabba <tabba@google.com> wrote:
> > > > >
> > > > > Certain VM IOCTLs are tied to specific VM features. Since pKVM does not
> > > > > support all features, restrict which IOCTLs are allowed depending on
> > > > > whether the associated feature is supported.
> > > > >
> > > > > Use the existing VM capability check as the source of truth to whether
> > > > > an IOCTL is allowed for a particular VM by mapping the IOCTLs with their
> > > > > associated capabilities.
> > > > >
> > > > > Suggested-by: Oliver Upton <oupton@kernel.org>
> > > > > Signed-off-by: Fuad Tabba <tabba@google.com>
> > > > > ---
> > > > >  arch/arm64/include/asm/kvm_pkvm.h | 21 +++++++++++++++++++++
> > > > >  arch/arm64/kvm/arm.c              |  3 +++
> > > > >  2 files changed, 24 insertions(+)
> > > > >
> > > > > diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> > > > > index 5b564576160d..0fa8c84816fd 100644
> > > > > --- a/arch/arm64/include/asm/kvm_pkvm.h
> > > > > +++ b/arch/arm64/include/asm/kvm_pkvm.h
> > > > > @@ -9,6 +9,7 @@
> > > > >  #include <linux/arm_ffa.h>
> > > > >  #include <linux/memblock.h>
> > > > >  #include <linux/scatterlist.h>
> > > > > +#include <asm/kvm_host.h>
> > > > >  #include <asm/kvm_pgtable.h>
> > > > >
> > > > >  /* Maximum number of VMs that can co-exist under pKVM. */
> > > > > @@ -43,6 +44,7 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
> > > > >       case KVM_CAP_ARM_SVE:
> > > > >       case KVM_CAP_ARM_PTRAUTH_ADDRESS:
> > > > >       case KVM_CAP_ARM_PTRAUTH_GENERIC:
> > > > > +     case KVM_CAP_ARM_BASIC:
> > > >
> > > > Can we instead rely on an existing VM capability? I'm not overly keen
> > > > exposing something new to userspace (KVM_CAP_ARM_BASIC) for something
> > > > that really is KVM's own internal problems.
> > > >
> > > > Looking at the history, a bunch of things have always been present:
> > > > KVM_CAP_NR_VCPUS, for example. You could even #define
> > > > KVM_CAP_ARM_BASIC to that if you want.
> > >
> > > I wasn't too crazy about that either. I like the idea of defining it
> > > as an alias of KVM_CAP_NR_VCPUS. I'll do that when I respin.
> >
> > I've done something [1]. If that works for you, let me know and I'll
> > just merge that.
> 
> That works for the previous patch (7/9), which is where you've made
> the change. But since the alias is defined in `arm.c` it wouldn't work
> in this patch (8/9), because the function kvm_pkvm_ext_allowed() is
> defined in  `asm/kvm_pkvm.h`.

I dropped it from patch 8/9 for the reason below.

> Defining the alias in `asm/kvm_pkvm.h`
> or in `asm/kvm_host.h` should solve this, since both files are visible
> in arm.c (and in kvm_pkvm.h in both cases).

Nope. The compiler spots that this is the same value twice in the
switch, and compile fails. I only kept it as syntactic sugar in arm.c,
but I could otherwise drop it entirely.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
  2026-01-15 18:03           ` Marc Zyngier
@ 2026-01-15 19:15             ` Fuad Tabba
  0 siblings, 0 replies; 17+ messages in thread
From: Fuad Tabba @ 2026-01-15 19:15 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin

On Thu, 15 Jan 2026 at 18:03, Marc Zyngier <maz@kernel.org> wrote:
>
> On Thu, 15 Jan 2026 16:14:39 +0000,
> Fuad Tabba <tabba@google.com> wrote:
> >
> > On Thu, 15 Jan 2026 at 16:05, Marc Zyngier <maz@kernel.org> wrote:
> > >
> > > On Thu, 15 Jan 2026 15:19:48 +0000,
> > > Fuad Tabba <tabba@google.com> wrote:
> > > >
> > > > Hi Marc,
> > > >
> > > > On Thu, 15 Jan 2026 at 15:03, Marc Zyngier <maz@kernel.org> wrote:
> > > > >
> > > > > On Thu, 11 Dec 2025 10:47:08 +0000,
> > > > > Fuad Tabba <tabba@google.com> wrote:
> > > > > >
> > > > > > Certain VM IOCTLs are tied to specific VM features. Since pKVM does not
> > > > > > support all features, restrict which IOCTLs are allowed depending on
> > > > > > whether the associated feature is supported.
> > > > > >
> > > > > > Use the existing VM capability check as the source of truth to whether
> > > > > > an IOCTL is allowed for a particular VM by mapping the IOCTLs with their
> > > > > > associated capabilities.
> > > > > >
> > > > > > Suggested-by: Oliver Upton <oupton@kernel.org>
> > > > > > Signed-off-by: Fuad Tabba <tabba@google.com>
> > > > > > ---
> > > > > >  arch/arm64/include/asm/kvm_pkvm.h | 21 +++++++++++++++++++++
> > > > > >  arch/arm64/kvm/arm.c              |  3 +++
> > > > > >  2 files changed, 24 insertions(+)
> > > > > >
> > > > > > diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> > > > > > index 5b564576160d..0fa8c84816fd 100644
> > > > > > --- a/arch/arm64/include/asm/kvm_pkvm.h
> > > > > > +++ b/arch/arm64/include/asm/kvm_pkvm.h
> > > > > > @@ -9,6 +9,7 @@
> > > > > >  #include <linux/arm_ffa.h>
> > > > > >  #include <linux/memblock.h>
> > > > > >  #include <linux/scatterlist.h>
> > > > > > +#include <asm/kvm_host.h>
> > > > > >  #include <asm/kvm_pgtable.h>
> > > > > >
> > > > > >  /* Maximum number of VMs that can co-exist under pKVM. */
> > > > > > @@ -43,6 +44,7 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
> > > > > >       case KVM_CAP_ARM_SVE:
> > > > > >       case KVM_CAP_ARM_PTRAUTH_ADDRESS:
> > > > > >       case KVM_CAP_ARM_PTRAUTH_GENERIC:
> > > > > > +     case KVM_CAP_ARM_BASIC:
> > > > >
> > > > > Can we instead rely on an existing VM capability? I'm not overly keen
> > > > > exposing something new to userspace (KVM_CAP_ARM_BASIC) for something
> > > > > that really is KVM's own internal problems.
> > > > >
> > > > > Looking at the history, a bunch of things have always been present:
> > > > > KVM_CAP_NR_VCPUS, for example. You could even #define
> > > > > KVM_CAP_ARM_BASIC to that if you want.
> > > >
> > > > I wasn't too crazy about that either. I like the idea of defining it
> > > > as an alias of KVM_CAP_NR_VCPUS. I'll do that when I respin.
> > >
> > > I've done something [1]. If that works for you, let me know and I'll
> > > just merge that.
> >
> > That works for the previous patch (7/9), which is where you've made
> > the change. But since the alias is defined in `arm.c` it wouldn't work
> > in this patch (8/9), because the function kvm_pkvm_ext_allowed() is
> > defined in  `asm/kvm_pkvm.h`.
>
> I dropped it from patch 8/9 for the reason below.
>
> > Defining the alias in `asm/kvm_pkvm.h`
> > or in `asm/kvm_host.h` should solve this, since both files are visible
> > in arm.c (and in kvm_pkvm.h in both cases).
>
> Nope. The compiler spots that this is the same value twice in the
> switch, and compile fails. I only kept it as syntactic sugar in arm.c,
> but I could otherwise drop it entirely.

I see. Thanks for fixing this Marc!
/fuad
>
> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling
  2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
                   ` (8 preceding siblings ...)
  2025-12-11 10:47 ` [PATCH v6 9/9] KVM: arm64: Prevent host from managing timer offsets for protected VMs Fuad Tabba
@ 2026-01-15 21:55 ` Marc Zyngier
  9 siblings, 0 replies; 17+ messages in thread
From: Marc Zyngier @ 2026-01-15 21:55 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, Fuad Tabba
  Cc: will, joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
	vladimir.murzin, Oliver Upton

On Thu, 11 Dec 2025 10:47:00 +0000, Fuad Tabba wrote:
> This series contains several fixes for guest feature trapping and
> enabling in pKVM, as well as a bit of tidying up.
> 
> Changes from v6 [1]:
> - Fixes to the patch that tracks KVM IOCTLs and their associated KVM
>   caps. Move static header data and function definitions to arm.c.
> - Introduce a capability KVM_CAP_ARM_BASIC instead of KVM_CAP_CORE,
>   since it is ARM-specific and that it only checks basic ARM ioctls.
> - Tidying up code and commit messages.
> - Based on Linux 6.18
> 
> [...]

Applied to next, thanks!

[1/9] KVM: arm64: Fix Trace Buffer trapping for protected VMs
      commit: 288eb55483c05bc37379a781d0d18b8e6c280f92
[2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
      commit: e913c7ce9e6f62038a486218f43f699fc443e3e1
[3/9] KVM: arm64: Fix MTE flag initialization for protected VMs
      commit: ebbcaece84738f71b35f32339bdeb8776004e641
[4/9] KVM: arm64: Introduce helper to calculate fault IPA offset
      commit: c273feee70bd3d8c6c4d5efaf6b3ae945c839378
[5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM
      commit: 43a21a0f0c4ab7de755f2cee2ff4700f26fe0bba
[6/9] KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest in pKVM
      commit: f4eee308c8f4013a52bd7d7735e64b5127c1b4a8
[7/9] KVM: arm64: Track KVM IOCTLs and their associated KVM caps
      commit: 8823485a697de5c280a7a2632620338722f16663
[8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
      commit: b12b3b04f6ba072ca5a618a75e546c996be94bd1
[9/9] KVM: arm64: Prevent host from managing timer offsets for protected VMs
      commit: f7d05ee84a6a8d3775e0f0c3070d9380bed844a9

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2026-01-15 21:55 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-11 10:47 [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
2025-12-11 10:47 ` [PATCH v6 1/9] KVM: arm64: Fix Trace Buffer trapping for protected VMs Fuad Tabba
2025-12-11 10:47 ` [PATCH v6 2/9] KVM: arm64: Fix Trace Buffer trap polarity " Fuad Tabba
2025-12-11 10:47 ` [PATCH v6 3/9] KVM: arm64: Fix MTE flag initialization " Fuad Tabba
2025-12-11 10:47 ` [PATCH v6 4/9] KVM: arm64: Introduce helper to calculate fault IPA offset Fuad Tabba
2025-12-11 10:47 ` [PATCH v6 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM Fuad Tabba
2025-12-11 10:47 ` [PATCH v6 6/9] KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest " Fuad Tabba
2025-12-11 10:47 ` [PATCH v6 7/9] KVM: arm64: Track KVM IOCTLs and their associated KVM caps Fuad Tabba
2025-12-11 10:47 ` [PATCH v6 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM Fuad Tabba
2026-01-15 15:03   ` Marc Zyngier
2026-01-15 15:19     ` Fuad Tabba
2026-01-15 16:05       ` Marc Zyngier
2026-01-15 16:14         ` Fuad Tabba
2026-01-15 18:03           ` Marc Zyngier
2026-01-15 19:15             ` Fuad Tabba
2025-12-11 10:47 ` [PATCH v6 9/9] KVM: arm64: Prevent host from managing timer offsets for protected VMs Fuad Tabba
2026-01-15 21:55 ` [PATCH v6 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox