* [PATCH v2 0/2] KVM: arm64: vgic-v4: Don't allocate vPEs that a VM can't use
@ 2026-10-28 10:13 Fuad Tabba
2026-10-28 10:13 ` [PATCH v2 1/2] KVM: arm64: vgic-v4: Don't allocate vPEs for a GICv2 VM Fuad Tabba
2026-10-28 10:13 ` [PATCH v2 2/2] KVM: arm64: vgic-v4: Don't allocate vPEs when userspace clears nASSGIcap Fuad Tabba
0 siblings, 2 replies; 3+ messages in thread
From: Fuad Tabba @ 2026-10-28 10:13 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton
Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu,
Raghavendra Rao Ananta, Eric Auger, Sascha Bischoff, Will Deacon,
Fuad Tabba, kvmarm, linux-arm-kernel, linux-kernel
Hi folks,
Changes since v1 [1]:
- Gate vgic_v4_init() on vgic_supports_vpes(), split out of
vgic_supports_direct_msis(), instead of open coding the nASSGIcap
check. (Oliver)
- Use vgic_is_v3() for the GICv2 check, in vgic_supports_vpes(). (Oliver)
Two fixes for vgic_its_create() allocating vPEs for a VM that never
uses them. Nothing frees them when the VM is destroyed, and each
doorbell handler stays registered with a freed vCPU.
The first is for a GICv2 VM, which KVM can run on a GICv4.0 host whose
CPU interface supports legacy operation. The second is for a GICv3 VM
whose VMM cleared nASSGIcap on a GICv4.1 host with vSGIs.
The second patch also moves the first one's GICv3 check into
vgic_supports_vpes(). I kept them separate because the first can be
backported on its own to stable kernels that predate nASSGIcap, which
is also why it open codes the check: vgic_is_v3() only exists since
7.1. The end state is what Oliver asked for.
Tested on AEM FVP, with has-gicv4.1=0 for the GICv2 case and =1 for the
other. With my reproducer (clear nASSGIcap for the second case,
initialise the vgic, create an ITS, destroy the VM), the kernel without
the fix leaves four "vcpu" doorbells in /proc/interrupts in each case,
and the fixed one doesn't leave any.
Based on Linux 7.3-rc3 (fd73f4a665989).
Cheers,
/fuad
[1] https://lore.kernel.org/all/20261026152639.3926498-1-fuad.tabba@linux.dev/
Fuad Tabba (2):
KVM: arm64: vgic-v4: Don't allocate vPEs for a GICv2 VM
KVM: arm64: vgic-v4: Don't allocate vPEs when userspace clears
nASSGIcap
arch/arm64/kvm/vgic/vgic-mmio-v3.c | 9 +++++++--
arch/arm64/kvm/vgic/vgic-v4.c | 2 +-
arch/arm64/kvm/vgic/vgic.h | 1 +
3 files changed, 9 insertions(+), 3 deletions(-)
base-commit: fd73f4a6659897191fa0d40695fe370925dd3780
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v2 1/2] KVM: arm64: vgic-v4: Don't allocate vPEs for a GICv2 VM
2026-10-28 10:13 [PATCH v2 0/2] KVM: arm64: vgic-v4: Don't allocate vPEs that a VM can't use Fuad Tabba
@ 2026-10-28 10:13 ` Fuad Tabba
2026-10-28 10:13 ` [PATCH v2 2/2] KVM: arm64: vgic-v4: Don't allocate vPEs when userspace clears nASSGIcap Fuad Tabba
1 sibling, 0 replies; 3+ messages in thread
From: Fuad Tabba @ 2026-10-28 10:13 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton
Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu,
Raghavendra Rao Ananta, Eric Auger, Sascha Bischoff, Will Deacon,
Fuad Tabba, kvmarm, linux-arm-kernel, linux-kernel
KVM can run a GICv2 VM on a GICv4.0 host whose CPU interface supports
legacy operation. Such a VM has no LPIs and never uses vPEs, so
vgic_supports_direct_irqs() is false for it and kvm_vgic_dist_destroy()
never tears them down. However, userspace can still create an ITS for
it. Once the vgic is initialised, vgic_its_create() calls
vgic_v4_init(), which allocates the vPEs and requests a doorbell IRQ for
each vCPU. They're then never freed, and each doorbell handler stays
registered with a vCPU that's freed with the VM.
Only allocate vPEs for a GICv3 VM.
Fixes: 74fe55dc9ab77 ("KVM: arm/arm64: GICv4: Add init/teardown of the per-VM vPE irq domain")
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
arch/arm64/kvm/vgic/vgic-v4.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
index ed236f083f0d7..a01de4de608a6 100644
--- a/arch/arm64/kvm/vgic/vgic-v4.c
+++ b/arch/arm64/kvm/vgic/vgic-v4.c
@@ -248,7 +248,7 @@ int vgic_v4_init(struct kvm *kvm)
lockdep_assert_held(&kvm->arch.config_lock);
- if (!kvm_vgic_global_state.has_gicv4)
+ if (!kvm_vgic_global_state.has_gicv4 || dist->vgic_model != KVM_DEV_TYPE_ARM_VGIC_V3)
return 0; /* Nothing to see here... move along. */
if (dist->its_vm.vpes)
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v2 2/2] KVM: arm64: vgic-v4: Don't allocate vPEs when userspace clears nASSGIcap
2026-10-28 10:13 [PATCH v2 0/2] KVM: arm64: vgic-v4: Don't allocate vPEs that a VM can't use Fuad Tabba
2026-10-28 10:13 ` [PATCH v2 1/2] KVM: arm64: vgic-v4: Don't allocate vPEs for a GICv2 VM Fuad Tabba
@ 2026-10-28 10:13 ` Fuad Tabba
1 sibling, 0 replies; 3+ messages in thread
From: Fuad Tabba @ 2026-10-28 10:13 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton
Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu,
Raghavendra Rao Ananta, Eric Auger, Sascha Bischoff, Will Deacon,
Fuad Tabba, kvmarm, linux-arm-kernel, linux-kernel
Since commit c652887a92887 ("KVM: arm64: vgic-v3: Allow userspace to
write GICD_TYPER2.nASSGIcap"), userspace can disable vPE allocation for
a VM on a GICv4.1 host with vSGIs by clearing nASSGIcap before the vgic
is initialised. vgic_init() then skips vgic_v4_init(), and
kvm_vgic_dist_destroy() skips vgic_v4_teardown(). vgic_its_create()
still calls vgic_v4_init() for an ITS created after the vgic is
initialised, though, and vgic_v4_init() allocates the vPEs and requests
a doorbell IRQ for each vCPU. Destroying the VM leaks them, and leaves
each doorbell handler registered with a vCPU that's about to be freed.
Move the part of vgic_supports_direct_msis() that doesn't depend on the
ITS into vgic_supports_vpes(), together with vgic_v4_init()'s GICv3
check. Gate vgic_v4_init() on it rather than on
vgic_supports_direct_irqs(), which reads has_its before
vgic_its_create() sets it. vgic_supports_direct_msis() returns what it
did before, since vgic_has_its() is already false for a non-GICv3 VM.
Fixes: c652887a92887 ("KVM: arm64: vgic-v3: Allow userspace to write GICD_TYPER2.nASSGIcap")
Suggested-by: Oliver Upton <oupton@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
arch/arm64/kvm/vgic/vgic-mmio-v3.c | 9 +++++++--
arch/arm64/kvm/vgic/vgic-v4.c | 2 +-
arch/arm64/kvm/vgic/vgic.h | 1 +
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
index 5913a20d83019..a60697238a7a7 100644
--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
@@ -48,7 +48,7 @@ bool vgic_has_its(struct kvm *kvm)
return dist->has_its;
}
-bool vgic_supports_direct_msis(struct kvm *kvm)
+bool vgic_supports_vpes(struct kvm *kvm)
{
/*
* Deliberately conflate vLPI and vSGI support on GICv4.1 hardware,
@@ -58,7 +58,12 @@ bool vgic_supports_direct_msis(struct kvm *kvm)
if (system_supports_direct_sgis() && !vgic_supports_direct_sgis(kvm))
return false;
- return kvm_vgic_global_state.has_gicv4 && vgic_has_its(kvm);
+ return kvm_vgic_global_state.has_gicv4 && vgic_is_v3(kvm);
+}
+
+bool vgic_supports_direct_msis(struct kvm *kvm)
+{
+ return vgic_supports_vpes(kvm) && vgic_has_its(kvm);
}
bool system_supports_direct_sgis(void)
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
index a01de4de608a6..0a4b9a74425b4 100644
--- a/arch/arm64/kvm/vgic/vgic-v4.c
+++ b/arch/arm64/kvm/vgic/vgic-v4.c
@@ -248,7 +248,7 @@ int vgic_v4_init(struct kvm *kvm)
lockdep_assert_held(&kvm->arch.config_lock);
- if (!kvm_vgic_global_state.has_gicv4 || dist->vgic_model != KVM_DEV_TYPE_ARM_VGIC_V3)
+ if (!vgic_supports_vpes(kvm))
return 0; /* Nothing to see here... move along. */
if (dist->its_vm.vpes)
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index b71d486ae5145..7fc29a395a7db 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -500,6 +500,7 @@ static inline bool vgic_host_has_gicv5(void)
}
bool system_supports_direct_sgis(void);
+bool vgic_supports_vpes(struct kvm *kvm);
bool vgic_supports_direct_msis(struct kvm *kvm);
bool vgic_supports_direct_sgis(struct kvm *kvm);
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-28 10:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-28 10:13 [PATCH v2 0/2] KVM: arm64: vgic-v4: Don't allocate vPEs that a VM can't use Fuad Tabba
2026-10-28 10:13 ` [PATCH v2 1/2] KVM: arm64: vgic-v4: Don't allocate vPEs for a GICv2 VM Fuad Tabba
2026-10-28 10:13 ` [PATCH v2 2/2] KVM: arm64: vgic-v4: Don't allocate vPEs when userspace clears nASSGIcap Fuad Tabba
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®