All of lore.kernel.org
 help / color / mirror / Atom feed
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 <oupton@kernel.org>,
	Zenghui Yu <yuzenghui@huawei.com>,
	Christoffer Dall <christoffer.dall@arm.com>,
	Fuad Tabba <tabba@google.com>, Mark Brown <broonie@kernel.org>
Subject: [PATCH v4 09/49] KVM: arm64: Add LR overflow handling documentation
Date: Thu, 20 Nov 2025 17:24:59 +0000	[thread overview]
Message-ID: <20251120172540.2267180-10-maz@kernel.org> (raw)
In-Reply-To: <20251120172540.2267180-1-maz@kernel.org>

Add a bit of documentation describing how we are dealing with LR
overflow. This is mostly a braindump of how things are expected
to work. For now anyway.

Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/vgic/vgic.c | 81 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 80 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 6dd5a10081e27..7ee253a9fb77e 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -825,7 +825,86 @@ static int compute_ap_list_depth(struct kvm_vcpu *vcpu,
 	return count;
 }
 
-/* Requires the VCPU's ap_list_lock to be held. */
+/*
+ * Dealing with LR overflow is close to black magic -- dress accordingly.
+ *
+ * We have to present an almost infinite number of interrupts through a very
+ * limited number of registers. Therefore crucial decisions must be made to
+ * ensure we feed the most relevant interrupts into the LRs, and yet have
+ * some facilities to let the guest interact with those that are not there.
+ *
+ * All considerations below are in the context of interrupts targeting a
+ * single vcpu with non-idle state (either pending, active, or both),
+ * colloquially called the ap_list:
+ *
+ * - Pending interrupts must have priority over active interrupts. This also
+ *   excludes pending+active interrupts. This ensures that a guest can
+ *   perform priority drops on any number of interrupts, and yet be
+ *   presented the next pending one.
+ *
+ * - Deactivation of interrupts outside of the LRs must be tracked by using
+ *   either the EOIcount-driven maintenance interrupt, and sometimes by
+ *   trapping the DIR register.
+ *
+ * - For EOImode=0, a non-zero EOIcount means walking the ap_list past the
+ *   point that made it into the LRs, and deactivate interrupts that would
+ *   have made it onto the LRs if we had the space.
+ *
+ * - The MI-generation bits must be used to try and force an exit when the
+ *   guest has done enough changes to the LRs that we want to reevaluate the
+ *   situation:
+ *
+ *	- if the total number of pending interrupts exceeds the number of
+ *	  LR, NPIE must be set in order to exit once no pending interrupts
+ *	  are present in the LRs, allowing us to populate the next batch.
+ *
+ *	- if there are active interrupts outside of the LRs, then LRENPIE
+ *	  must be set so that we exit on deactivation of one of these, and
+ *	  work out which one is to be deactivated.  Note that this is not
+ *	  enough to deal with EOImode=1, see below.
+ *
+ *	- if the overall number of interrupts exceeds the number of LRs,
+ *	  then UIE must be set to allow refilling of the LRs once the
+ *	  majority of them has been processed.
+ *
+ *	- as usual, MI triggers are only an optimisation, since we cannot
+ *        rely on the MI being delivered in timely manner...
+ *
+ * - EOImode=1 creates some additional problems:
+ *
+ *      - deactivation can happen in any order, and we cannot rely on
+ *	  EOImode=0's coupling of priority-drop and deactivation which
+ *	  imposes strict reverse Ack order. This means that DIR must
+ *	  trap if we have active interrupts outside of the LRs.
+ *
+ *      - deactivation of SPIs can occur on any CPU, while the SPI is only
+ *	  present in the ap_list of the CPU that actually ack-ed it. In that
+ *	  case, EOIcount doesn't provide enough information, and we must
+ *	  resort to trapping DIR even if we don't overflow the LRs. Bonus
+ *	  point for not trapping DIR when no SPIs are pending or active in
+ *	  the whole VM.
+ *
+ *	- LPIs do not suffer the same problem as SPIs on deactivation, as we
+ *	  have to essentially discard the active state, see below.
+ *
+ * - Virtual LPIs have an active state (surprise!), which gets removed on
+ *   priority drop (EOI). However, EOIcount doesn't get bumped when the LPI
+ *   is not present in the LR (surprise again!). Special care must therefore
+ *   be taken to remove the active state from any activated LPI when exiting
+ *   from the guest. This is in a way no different from what happens on the
+ *   physical side. We still rely on the running priority to have been
+ *   removed from the APRs, irrespective of the LPI being present in the LRs
+ *   or not.
+ *
+ * - Virtual SGIs directly injected via GICv4.1 must not affect EOIcount, as
+ *   they are not managed in SW and don't have a true active state. So only
+ *   set vSGIEOICount when no SGIs are in the ap_list.
+ *
+ * - GICv2 SGIs with multiple sources are injected one source at a time, as
+ *   if they were made pending sequentially. This may mean that we don't
+ *   always present the HPPI if other interrupts with lower priority are
+ *   pending in the LRs. Big deal.
+ */
 static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
 {
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-- 
2.47.3


  parent reply	other threads:[~2025-11-20 17:25 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-20 17:24 [PATCH v4 00/49] KVM: arm64: Add LR overflow infrastructure (the final one, I swear!) Marc Zyngier
2025-11-20 17:24 ` [PATCH v4 01/49] irqchip/gic: Add missing GICH_HCR control bits Marc Zyngier
2025-11-20 17:24 ` [PATCH v4 02/49] irqchip/gic: Expose CPU interface VA to KVM Marc Zyngier
2025-11-20 17:24 ` [PATCH v4 03/49] irqchip/apple-aic: Spit out ICH_MISR_EL2 value on spurious vGIC MI Marc Zyngier
2025-11-20 17:24 ` [PATCH v4 04/49] KVM: arm64: Turn vgic-v3 errata traps into a patched-in constant Marc Zyngier
2025-11-20 17:24 ` [PATCH v4 05/49] KVM: arm64: vgic-v3: Fix GICv3 trapping in protected mode Marc Zyngier
2025-11-20 17:24 ` [PATCH v4 06/49] KVM: arm64: GICv3: Detect and work around the lack of ICV_DIR_EL1 trapping Marc Zyngier
2025-11-25 11:26   ` Suzuki K Poulose
2025-11-25 13:48     ` Marc Zyngier
2025-11-25 14:14       ` Suzuki K Poulose
2025-11-25 15:01         ` Marc Zyngier
2025-11-25 15:03           ` Suzuki K Poulose
2025-11-20 17:24 ` [PATCH v4 07/49] KVM: arm64: Repack struct vgic_irq fields Marc Zyngier
2025-11-20 17:24 ` [PATCH v4 08/49] KVM: arm64: Add tracking of vgic_irq being present in a LR Marc Zyngier
2025-11-20 17:24 ` Marc Zyngier [this message]
2025-11-20 17:25 ` [PATCH v4 10/49] KVM: arm64: GICv3: Drop LPI active state when folding LRs Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 11/49] KVM: arm64: GICv3: Preserve EOIcount on exit Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 12/49] KVM: arm64: GICv3: Decouple ICH_HCR_EL2 programming from LRs Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 13/49] KVM: arm64: GICv3: Extract LR folding primitive Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 14/49] KVM: arm64: GICv3: Extract LR computing primitive Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 15/49] KVM: arm64: GICv2: Preserve EOIcount on exit Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 16/49] KVM: arm64: GICv2: Decouple GICH_HCR programming from LRs being loaded Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 17/49] KVM: arm64: GICv2: Extract LR folding primitive Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 18/49] KVM: arm64: GICv2: Extract LR computing primitive Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 19/49] KVM: arm64: Compute vgic state irrespective of the number of interrupts Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 20/49] KVM: arm64: Eagerly save VMCR on exit Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 21/49] KVM: arm64: Revamp vgic maintenance interrupt configuration Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 22/49] KVM: arm64: Turn kvm_vgic_vcpu_enable() into kvm_vgic_vcpu_reset() Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 23/49] KVM: arm64: Make vgic_target_oracle() globally available Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 24/49] KVM: arm64: Invert ap_list sorting to push active interrupts out Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 25/49] KVM: arm64: Move undeliverable interrupts to the end of ap_list Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 26/49] KVM: arm64: Use MI to detect groups being enabled/disabled Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 27/49] KVM: arm64: GICv3: Handle LR overflow when EOImode==0 Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 28/49] KVM: arm64: GICv3: Handle deactivation via ICV_DIR_EL1 traps Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 29/49] KVM: arm64: GICv3: Add GICv2 SGI handling to deactivation primitive Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 30/49] KVM: arm64: GICv3: Set ICH_HCR_EL2.TDIR when interrupts overflow LR capacity Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 31/49] KVM: arm64: GICv3: Add SPI tracking to handle asymmetric deactivation Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 32/49] KVM: arm64: GICv3: Handle in-LR deactivation when possible Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 33/49] KVM: arm64: GICv3: Avoid broadcast kick on CPUs lacking TDIR Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 34/49] KVM: arm64: GICv3: nv: Resync LRs/VMCR/HCR early for better MI emulation Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 35/49] KVM: arm64: GICv3: nv: Plug L1 LR sync into deactivation primitive Marc Zyngier
2026-03-30 11:51   ` Vishnu Pajjuri
2026-03-30 12:17     ` Marc Zyngier
2026-03-31  6:31       ` Vishnu Pajjuri
2026-03-31  9:42         ` Marc Zyngier
2026-04-22  6:55           ` Marc Zyngier
2026-04-22 14:57             ` Vishnu Pajjuri
2026-04-26  9:14               ` Marc Zyngier
2026-04-26 14:07                 ` Marc Zyngier
2026-04-28 20:37                   ` Marc Zyngier
2026-04-24  0:02             ` Darren Hart
2025-11-20 17:25 ` [PATCH v4 36/49] KVM: arm64: GICv3: Force exit to sync ICH_HCR_EL2.En Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 37/49] KVM: arm64: GICv2: Handle LR overflow when EOImode==0 Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 38/49] KVM: arm64: GICv2: Handle deactivation via GICV_DIR traps Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 39/49] KVM: arm64: GICv2: Always trap GICV_DIR register Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 40/49] KVM: arm64: selftests: gic_v3: Add irq group setting helper Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 41/49] KVM: arm64: selftests: gic_v3: Disable Group-0 interrupts by default Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 42/49] KVM: arm64: selftests: vgic_irq: Fix GUEST_ASSERT_IAR_EMPTY() helper Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 43/49] KVM: arm64: selftests: vgic_irq: Change configuration before enabling interrupt Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 44/49] KVM: arm64: selftests: vgic_irq: Exclude timer-controlled interrupts Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 45/49] KVM: arm64: selftests: vgic_irq: Remove LR-bound limitation Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 46/49] KVM: arm64: selftests: vgic_irq: Perform EOImode==1 deactivation in ack order Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 47/49] KVM: arm64: selftests: vgic_irq: Add asymmetric SPI deaectivation test Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 48/49] KVM: arm64: selftests: vgic_irq: Add Group-0 enable test Marc Zyngier
2025-11-20 17:25 ` [PATCH v4 49/49] KVM: arm64: selftests: vgic_irq: Add timer deactivation test Marc Zyngier
2025-11-21 14:15 ` [PATCH v4 00/49] KVM: arm64: Add LR overflow infrastructure (the final one, I swear!) Mark Brown
2025-11-24 22:44 ` Oliver Upton

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=20251120172540.2267180-10-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=broonie@kernel.org \
    --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=oupton@kernel.org \
    --cc=suzuki.poulose@arm.com \
    --cc=tabba@google.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.