With GICv5, timer PPIs use architecturally defined IDs, and therefore
we require userspace to use the architected IDs too. We perform this
validation in timer_irqs_are_valid(), which validates the configured
PPI after claiming it with kvm_vgic_set_owner(). This is obviously the
wrong order, and could both result in a NULL pointer dereference for
an ID >= 64 and in an incorrect ownership claim.
Switch the order to first validate the PPI before setting the
owner. This both prevents an invalid GICv5 timer PPI from reaching the
IRQ lookup, and avoids claiming an IRQ for a timer configuration that
will be rejected.
Fixes: 06c85b58e0b1 ("KVM: arm64: Move GICv5 timer PPI validation into timer_irqs_are_valid()")
Link: https://sashiko.dev/#/message/20260810111614.DDC731F000E9%40smtp.kernel.org
Signed-off-by: Sascha Bischoff <redacted>
---
arch/arm64/kvm/arch_timer.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 4155fe89b58a1..af7e2894cd690 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -1529,13 +1529,14 @@ static bool timer_irqs_are_valid(struct kvm_vcpu *vcpu)
ctx = vcpu_get_timer(vcpu, i);
irq = timer_irq(ctx);
- if (kvm_vgic_set_owner(vcpu, irq, ctx))
- break;
/* With GICv5, the default PPI is what you get -- nothing else */
if (vgic_is_v5(vcpu->kvm) && irq != get_vgic_ppi(vcpu->kvm, default_ppi[i]))
break;
+ if (kvm_vgic_set_owner(vcpu, irq, ctx))
+ break;
+
/*
* We know by construction that we only have PPIs, so all values
* are less than 32 for non-GICv5 VGICs. On GICv5, they are
--
2.34.1