public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH 0/4] KVM: arm64: Don't perform vgic-v2 lazy init on timer injection
@ 2026-04-17 12:46 Marc Zyngier
  2026-04-17 12:46 ` [PATCH 1/4] KVM: arm64: timer: Repaint kvm_timer_should_fire() to kvm_timer_pending() Marc Zyngier
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Marc Zyngier @ 2026-04-17 12:46 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: Deepanshu Kartikey, Joey Gouly, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu

Syzkaller reported an interesting case [1] showing vgic-v2 being
initialised via the lazy init path on injection from the timer reset
path. Yes, that's convoluted. This resulted in a splat as we could
end-up scheduling in an atomic context.

Deepanshu proposed [2] a simple fix that unconditionally init'd the
GIC on vcpu reset. While this would do the trick, this is only
papering over the real issue.

The situation is that we currently have three ways to lazily init the
vgic:

- on first run of any vcpu
- on access from userspace injecting an interrupt
- on access from the kernel injecting an interrupt

The splat is caused by this last one, and it is interesting to drill
into why we end-up with it.

All guest interrupts generated by the kernel itself are level. Which
means that they cannot be lost unless the generating device is being
interacted with. So there shouldn't be any need to initialise the vgic
for that reason, and we could defer it to the first run of a vcpu.

However, the timers are extra special. Each one has its own little
single bit cache that contains the last level set. And as long as the
level doesn't change, the timer code doesn't call into the interrupt
injection code, making it totally optimal.

A side effect of this optimisation is that the level interrupt
effectively becomes an edge (only the changes are reported). Which
means that the interrupt must be recorded in the vgic, or it be
forever lost. Hence the need to eagerly initialise the GIC at
injection time.

But frankly, there isn't much to gain by having this cache. All we
avoid is a lookup, an uncontended lock, and an early return. The other
interrupts generated by the kernel (PMU, vgic MI) don't have such
cache, and nobody has complained yet.

So let's drop this cache, and remove the vgic init from the kernel
injection. If someone shouts about a loss of performance, then let's
improve the interrupt injection itself, and not paper over it. Also
use this opportunity to repaint kvm_timer_should_fire() as
kvm_timer_pending(), something that is way less ambiguous.

Patches on top of kvmarm-7.1. The reproducer didn't trigger on my
boxes, and syzkaller is down at the moment. But nothing bad happened
in my testing...

[1] https://syzkaller.appspot.com/bug?extid=12b178b7c756664d2518
[2] https://lore.kernel.org/r/20260412080437.38782-1-kartikey406@gmail.com

Marc Zyngier (4):
  KVM: arm64: timer: Repaint kvm_timer_should_fire() to
    kvm_timer_pending()
  KVM: arm64: timer: Kill the per-timer level cache
  KVM: arm64: vgic-v2: Force vgic init on injection from userspace
  KVM: arm64: vgic-v2: Don't init the vgic on in-kernel interrupt
    injection

 arch/arm64/kvm/arch_timer.c  | 44 ++++++++++++++++++------------------
 arch/arm64/kvm/arm.c         |  7 ++++++
 arch/arm64/kvm/vgic/vgic.c   |  6 ++---
 include/kvm/arm_arch_timer.h |  5 ----
 4 files changed, 31 insertions(+), 31 deletions(-)

-- 
2.47.3



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

end of thread, other threads:[~2026-04-17 15:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-17 12:46 [PATCH 0/4] KVM: arm64: Don't perform vgic-v2 lazy init on timer injection Marc Zyngier
2026-04-17 12:46 ` [PATCH 1/4] KVM: arm64: timer: Repaint kvm_timer_should_fire() to kvm_timer_pending() Marc Zyngier
2026-04-17 12:46 ` [PATCH 2/4] KVM: arm64: timer: Kill the per-timer level cache Marc Zyngier
2026-04-17 15:56   ` Marc Zyngier
2026-04-17 12:46 ` [PATCH 3/4] KVM: arm64: vgic-v2: Force vgic init on injection from userspace Marc Zyngier
2026-04-17 12:46 ` [PATCH 4/4] KVM: arm64: vgic-v2: Don't init the vgic on in-kernel interrupt injection Marc Zyngier

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