From: Marc Zyngier <maz@kernel.org>
To: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
kvm@vger.kernel.org
Cc: Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Oliver Upton <oliver.upton@linux.dev>,
Zenghui Yu <yuzenghui@huawei.com>,
Christoffer Dall <christoffer.dall@arm.com>,
Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
Subject: [PATCH 00/33] KVM: arm64: Add LR overflow infrastructure
Date: Mon, 3 Nov 2025 16:54:44 +0000 [thread overview]
Message-ID: <20251103165517.2960148-1-maz@kernel.org> (raw)
Despite being an awfully complex piece of software, the KVM vgic
implementation is not doing what it should in a number of cases:
- It behaves very badly when the number of in-flight interrupts
targeting a specific CPU exceed the number of list registers
(LRs). This is catastrophic with NV (Volodymyr triggered that one
with a Xen guest), but can easily be triggered without it. You just
have to activate more interrupts than the number of LRs to end-up
with a guest live-lock.
- Similar issues exist when making high-priority interrupts targeting
a group that isn't enabled.
Overall, this stems from the vgic implementation not sorting the
interrupts presented to the guest in the correct order (i.e. the one
expected by the architecture), and allow deactivation outside of the
window exposed by the LRs.
Unfortunately, the cure for this is pretty involved, and involves
adding a significant amount of complexity:
- Order the list as the architecture requires it, by starting with
placing the HPPIs at the forefront of the ap_list
- Handle deactivation for EOImode being 0 or 1, which is specially
annoying as we cannot easily find out which mode we're in, and we
need to handle both concurrently
- Deal with individual interrupt groups being enabled/disabled
- Deal with SPIs being acked on one CPU and deactivated on another
Implementation wise, this is about extracting the relevant primitive
from the existing code, making guest state available to the emulation
more eagerly, dealing with a lot more MI sources, and be creative
about trapping stuff. Oh, and of course dealing with broken HW,
because nothing would be fun if we didn't.
The eagle eyed reviewer will notice that this series doesn't provide
any selftest. That's on purpose: I'm still working on those, and I
could do with some reviewing while I'm finishing them, and plan to
post them with v2.
Marc Zyngier (33):
irqchip/gic: Add missing GICH_HCR control bits
irqchip/gic: Expose CPU interface VA to KVM
irqchip/apple-aic: Spit out ICH_MIDR_EL2 value on spurious vGIC MI
KVM: arm64: Turn vgic-v3 errata traps into a patched-in constant
KVM: arm64: GICv3: Detect and work around the lack of ICV_DIR_EL1
trapping
KVM: arm64: Repack struct vgic_irq fields
KVM: arm64: Add tracking of vgic_irq being present in a LR
KVM: arm64: Add LR overflow handling documentation
KVM: arm64: GICv3: Drop LPI active state when folding LRs
KVM: arm64: GICv3: Preserve EOIcount on exit
KVM: arm64: GICv3: Decouple ICH_HCR_EL2 programming from LRs
KVM: arm64: GICv3: Extract LR folding primitive
KVM: arm64: GICv3: Extract LR computing primitive
KVM: arm64: GICv2: Preserve EOIcount on exit
KVM: arm64: GICv2: Decouple GICH_HCR programming from LRs being loaded
KVM: arm64: GICv2: Extract LR folding primitive
KVM: arm64: GICv2: Extract LR computing primitive
KVM: arm64: Compute vgic state irrespective of the number of
interrupts
KVM: arm64: Eagerly save VMCR on exit
KVM: arm64: Revamp vgic maintenance interrupt configuration
KVM: arm64: Make vgic_target_oracle() globally available
KVM: arm64: Invert ap_list sorting to push active interrupts out
KVM: arm64: Move undeliverable interrupts to the end of ap_list
KVM: arm64: Use MI to detect groups being enabled/disabled
KVM: arm64: Add AP-list overflow split/splice
KVM: arm64: GICv3: Handle LR overflow when EOImode==0
KVM: arm64: GICv3: Handle deactivation via ICV_DIR_EL1 traps
KVM: arm64: GICv3: Add GICv2 SGI handling to deactivation primitive
KVM: arm64: GICv3: Set ICH_HCR_EL2.TDIR when interrupts overflow LR
capacity
KVM: arm64: GICv2: Handle LR overflow when EOImode==0
KVM: arm64: GICv2: Handle deactivation via GICV_DIR traps
KVM: arm64: GICv2: Always trap GICV_DIR register
KVM: arm64: GICv3: Add SPI tracking to handle asymmetric deactivation
arch/arm64/include/asm/kvm_asm.h | 2 +-
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/include/asm/kvm_hyp.h | 2 +-
arch/arm64/include/asm/virt.h | 7 +-
arch/arm64/kernel/cpufeature.c | 34 ++
arch/arm64/kernel/hyp-stub.S | 5 +
arch/arm64/kernel/image-vars.h | 1 +
arch/arm64/kvm/arm.c | 7 +-
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 7 +-
arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c | 4 +
arch/arm64/kvm/hyp/vgic-v3-sr.c | 55 +--
arch/arm64/kvm/sys_regs.c | 19 +-
arch/arm64/kvm/vgic/vgic-init.c | 3 +
arch/arm64/kvm/vgic/vgic-mmio-v2.c | 24 ++
arch/arm64/kvm/vgic/vgic-mmio.h | 1 +
arch/arm64/kvm/vgic/vgic-v2.c | 311 +++++++++++++----
arch/arm64/kvm/vgic/vgic-v3-nested.c | 11 +-
arch/arm64/kvm/vgic/vgic-v3.c | 419 ++++++++++++++++++-----
arch/arm64/kvm/vgic/vgic-v4.c | 5 +-
arch/arm64/kvm/vgic/vgic.c | 328 ++++++++++++------
arch/arm64/kvm/vgic/vgic.h | 44 ++-
arch/arm64/tools/cpucaps | 1 +
drivers/irqchip/irq-apple-aic.c | 7 +-
drivers/irqchip/irq-gic.c | 3 +
include/kvm/arm_vgic.h | 35 +-
include/linux/irqchip/arm-gic.h | 6 +
include/linux/irqchip/arm-vgic-info.h | 2 +
27 files changed, 1012 insertions(+), 332 deletions(-)
--
2.47.3
next reply other threads:[~2025-11-03 16:55 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-03 16:54 Marc Zyngier [this message]
2025-11-03 16:54 ` [PATCH 01/33] irqchip/gic: Add missing GICH_HCR control bits Marc Zyngier
2025-11-03 16:54 ` [PATCH 02/33] irqchip/gic: Expose CPU interface VA to KVM Marc Zyngier
2025-11-03 16:54 ` [PATCH 03/33] irqchip/apple-aic: Spit out ICH_MIDR_EL2 value on spurious vGIC MI Marc Zyngier
2025-11-04 11:13 ` Zenghui Yu
2025-11-03 16:54 ` [PATCH 04/33] KVM: arm64: Turn vgic-v3 errata traps into a patched-in constant Marc Zyngier
2025-11-03 16:54 ` [PATCH 05/33] KVM: arm64: GICv3: Detect and work around the lack of ICV_DIR_EL1 trapping Marc Zyngier
2025-11-04 8:50 ` Yao Yuan
2025-11-04 9:04 ` Marc Zyngier
2025-11-04 9:40 ` Yao Yuan
2025-11-05 2:01 ` kernel test robot
2025-11-05 11:31 ` Marc Zyngier
2025-11-03 16:54 ` [PATCH 06/33] KVM: arm64: Repack struct vgic_irq fields Marc Zyngier
2025-11-03 16:54 ` [PATCH 07/33] KVM: arm64: Add tracking of vgic_irq being present in a LR Marc Zyngier
2025-11-03 16:54 ` [PATCH 08/33] KVM: arm64: Add LR overflow handling documentation Marc Zyngier
2025-11-03 16:54 ` [PATCH 09/33] KVM: arm64: GICv3: Drop LPI active state when folding LRs Marc Zyngier
2025-11-03 16:54 ` [PATCH 10/33] KVM: arm64: GICv3: Preserve EOIcount on exit Marc Zyngier
2025-11-03 16:54 ` [PATCH 11/33] KVM: arm64: GICv3: Decouple ICH_HCR_EL2 programming from LRs Marc Zyngier
2025-11-03 16:54 ` [PATCH 12/33] KVM: arm64: GICv3: Extract LR folding primitive Marc Zyngier
2025-11-03 16:54 ` [PATCH 13/33] KVM: arm64: GICv3: Extract LR computing primitive Marc Zyngier
2025-11-03 16:54 ` [PATCH 14/33] KVM: arm64: GICv2: Preserve EOIcount on exit Marc Zyngier
2025-11-03 16:54 ` [PATCH 15/33] KVM: arm64: GICv2: Decouple GICH_HCR programming from LRs being loaded Marc Zyngier
2025-11-03 16:55 ` [PATCH 16/33] KVM: arm64: GICv2: Extract LR folding primitive Marc Zyngier
2025-11-03 16:55 ` [PATCH 17/33] KVM: arm64: GICv2: Extract LR computing primitive Marc Zyngier
2025-11-03 16:55 ` [PATCH 18/33] KVM: arm64: Compute vgic state irrespective of the number of interrupts Marc Zyngier
2025-11-03 16:55 ` [PATCH 19/33] KVM: arm64: Eagerly save VMCR on exit Marc Zyngier
2025-11-03 16:55 ` [PATCH 20/33] KVM: arm64: Revamp vgic maintenance interrupt configuration Marc Zyngier
2025-11-03 16:55 ` [PATCH 21/33] KVM: arm64: Make vgic_target_oracle() globally available Marc Zyngier
2025-11-03 16:55 ` [PATCH 22/33] KVM: arm64: Invert ap_list sorting to push active interrupts out Marc Zyngier
2025-11-03 16:55 ` [PATCH 23/33] KVM: arm64: Move undeliverable interrupts to the end of ap_list Marc Zyngier
2025-11-03 16:55 ` [PATCH 24/33] KVM: arm64: Use MI to detect groups being enabled/disabled Marc Zyngier
2025-11-03 16:55 ` [PATCH 25/33] KVM: arm64: Add AP-list overflow split/splice Marc Zyngier
2025-11-03 16:55 ` [PATCH 26/33] KVM: arm64: GICv3: Handle LR overflow when EOImode==0 Marc Zyngier
2025-11-03 16:55 ` [PATCH 27/33] KVM: arm64: GICv3: Handle deactivation via ICV_DIR_EL1 traps Marc Zyngier
2025-11-03 16:55 ` [PATCH 28/33] KVM: arm64: GICv3: Add GICv2 SGI handling to deactivation primitive Marc Zyngier
2025-11-03 16:55 ` [PATCH 29/33] KVM: arm64: GICv3: Set ICH_HCR_EL2.TDIR when interrupts overflow LR capacity Marc Zyngier
2025-11-03 16:55 ` [PATCH 30/33] KVM: arm64: GICv2: Handle LR overflow when EOImode==0 Marc Zyngier
2025-11-03 16:55 ` [PATCH 31/33] KVM: arm64: GICv2: Handle deactivation via GICV_DIR traps Marc Zyngier
2025-11-03 16:55 ` [PATCH 32/33] KVM: arm64: GICv2: Always trap GICV_DIR register Marc Zyngier
2025-11-03 16:55 ` [PATCH 33/33] KVM: arm64: GICv3: Add SPI tracking to handle asymmetric deactivation 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=20251103165517.2960148-1-maz@kernel.org \
--to=maz@kernel.org \
--cc=Volodymyr_Babchuk@epam.com \
--cc=christoffer.dall@arm.com \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=oliver.upton@linux.dev \
--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;
as well as URLs for NNTP newsgroup(s).