public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: Marc Zyngier <maz@kernel.org>
To: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org
Cc: Deepanshu Kartikey <kartikey406@gmail.com>,
	Joey Gouly <joey.gouly@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Oliver Upton <oupton@kernel.org>,
	Zenghui Yu <yuzenghui@huawei.com>
Subject: [PATCH 0/4] KVM: arm64: Don't perform vgic-v2 lazy init on timer injection
Date: Fri, 17 Apr 2026 13:46:08 +0100	[thread overview]
Message-ID: <20260417124612.2770268-1-maz@kernel.org> (raw)

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



             reply	other threads:[~2026-04-17 12:46 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-17 12:46 Marc Zyngier [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260417124612.2770268-1-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=joey.gouly@arm.com \
    --cc=kartikey406@gmail.com \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=oupton@kernel.org \
    --cc=suzuki.poulose@arm.com \
    --cc=yuzenghui@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox