WSL2-Linux-Kernel/virt/kvm/arm/vgic
Marc Zyngier 16ca6a607d KVM: arm/arm64: vgic: Don't populate multiple LRs with the same vintid
The vgic code is trying to be clever when injecting GICv2 SGIs,
and will happily populate LRs with the same interrupt number if
they come from multiple vcpus (after all, they are distinct
interrupt sources).

Unfortunately, this is against the letter of the architecture,
and the GICv2 architecture spec says "Each valid interrupt stored
in the List registers must have a unique VirtualID for that
virtual CPU interface.". GICv3 has similar (although slightly
ambiguous) restrictions.

This results in guests locking up when using GICv2-on-GICv3, for
example. The obvious fix is to stop trying so hard, and inject
a single vcpu per SGI per guest entry. After all, pending SGIs
with multiple source vcpus are pretty rare, and are mostly seen
in scenario where the physical CPUs are severely overcomitted.

But as we now only inject a single instance of a multi-source SGI per
vcpu entry, we may delay those interrupts for longer than strictly
necessary, and run the risk of injecting lower priority interrupts
in the meantime.

In order to address this, we adopt a three stage strategy:
- If we encounter a multi-source SGI in the AP list while computing
  its depth, we force the list to be sorted
- When populating the LRs, we prevent the injection of any interrupt
  of lower priority than that of the first multi-source SGI we've
  injected.
- Finally, the injection of a multi-source SGI triggers the request
  of a maintenance interrupt when there will be no pending interrupt
  in the LRs (HCR_NPIE).

At the point where the last pending interrupt in the LRs switches
from Pending to Active, the maintenance interrupt will be delivered,
allowing us to add the remaining SGIs using the same process.

Cc: stable@vger.kernel.org
Fixes: 0919e84c0f ("KVM: arm/arm64: vgic-new: Add IRQ sync/flush framework")
Acked-by: Christoffer Dall <cdall@kernel.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2018-03-14 18:31:04 +00:00
..
trace.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
vgic-debug.c KVM: arm/arm64: vgic: constify seq_operations and file_operations 2017-09-05 17:33:38 +02:00
vgic-init.c KVM: arm64: Fix GICv4 init when called from vgic_its_create 2018-01-12 11:40:21 +01:00
vgic-irqfd.c KVM: arm/arm64: vgic-irqfd: Fix MSI entry allocation 2017-11-29 16:46:12 +01:00
vgic-its.c KVM: arm: Use PTR_ERR_OR_ZERO() 2018-01-02 10:05:45 +01:00
vgic-kvm-device.c KVM: arm/arm64: Register iodevs when setting redist base and creating VCPUs 2017-05-09 12:19:36 +02:00
vgic-mmio-v2.c KVM: arm/arm64: Support calling vgic_update_irq_pending from irq context 2017-11-06 16:23:10 +01:00
vgic-mmio-v3.c KVM: arm/arm64: GICv4: Add property field and per-VM predicate 2017-11-10 09:06:45 +01:00
vgic-mmio.c KVM: arm/arm64: vgic: Add missing irq_lock to vgic_mmio_read_pending 2018-03-14 18:28:41 +00:00
vgic-mmio.h KVM: arm/arm64: Separate guest and uaccess writes to dist {sc}active 2017-05-23 12:48:11 +02:00
vgic-v2.c KVM: arm/arm64: vgic: Don't populate multiple LRs with the same vintid 2018-03-14 18:31:04 +00:00
vgic-v3.c KVM: arm/arm64: vgic: Don't populate multiple LRs with the same vintid 2018-03-14 18:31:04 +00:00
vgic-v4.c KVM: arm64: Fix GICv4 init when called from vgic_its_create 2018-01-12 11:40:21 +01:00
vgic.c KVM: arm/arm64: vgic: Don't populate multiple LRs with the same vintid 2018-03-14 18:31:04 +00:00
vgic.h KVM: arm/arm64: vgic: Don't populate multiple LRs with the same vintid 2018-03-14 18:31:04 +00:00