[PATCH v2 00/16] KVM: arm64: Add GICv5 ITS support

Sascha Bischoff sascha.bischoff at arm.com
Mon Nov 2 11:44:38 PST 2026


Hi all,

This is the second posting of my GICv5 KVM ITS series.

This series builds on the GICv5 IRS support now in 7.4-rc1 and adds
support for the GICv5 ITS, as described by the GICv5 specification
[1]. It allows a GICv5 guest to receive LPIs generated by MSIs,
including those from physical PCI devices mapped into the guest via
VFIO.

The ITS is exposed as a separate KVM device, alongside the VGICv5
device. The guest owns the device table and interrupt translation
tables. KVM walks these tables to resolve a DeviceID and EventID to an
LPI, and caches the result until the guest invalidates the relevant
translation or changes the table configuration.

The main pieces are:

* An emulated GICv5 ITS CONFIG_FRAME, including table configuration,
  event generation, and invalidation registers.

* Guest table walking for linear and two-level device and interrupt
  translation tables, together with a disposable XArray-based
  translation cache.

* MSI injection through KVM_SIGNAL_MSI and irqfd. GICv5 requires a
  DeviceID for each MSI, and the virtual ITS supports 16-bit EventIDs.

* Direct injection through the host ITS when an interrupt is forwarded
  to a vCPU. Forwarding teardown restores the host translation.

* Userspace attributes to configure the ITS address, access its
  registers, and reset the emulated state, together with ABI
  documentation.

* Selftests for the ITS attributes, guest table translation, MSI
  delivery, and guest-driven cache invalidation.

The guest tables remain the authoritative translation state. KVM's
cache can be discarded and rebuilt from guest memory; there is no
separate ITS table data for the VMM to save/restore.

Lorenzo's GICv5 Linux software enablement guide [2] describes how to
set up the GICv5 software stack. These changes have been tested on an
Arm FVP 11.32 release [3].

These changes are based on v7.4-rc1. The corresponding kvmtool patches
have been posted separately [4]. I plan to post an updated kvmtool
series shortly.

These changes are also available as a branch at [5]. For reference, v1
of this series can be found at [6].

This series applies independently of the host GICv5 fixes [7], but
concurrent use may encounter the host driver issues described there. A
branch with both series is available at [8]. Both series need to be
merged for the ITS support to be complete.

The main changes since v1 are:

* Rebased onto v7.4-rc1.

* Reused upstream ITS model tracking, removing the separate has_its
  state.

* Sashiko flagged some races for GICv3 LPIs, which were caused by me
  making the allocation common to both vITSes. Group 1 is set before
  adding the LPI to the tracking XArray. The GICv3 ITS path performs
  one initial lookup before allocating a new LPI.

* Replaced the translation cache hash table with an XArray. This
  avoids the locking/lockup issues raised by Sashiko. Furthermore, it
  is no longer possible for a malicious guest to force all LPI
  mappings into one hashtable bucket.

* Tightened translation and MSI handling: enforce advertised DeviceID
  and EventID limits, report invalid guest translations as blocked
  MSIs, and allow software injection to proceed if caching fails.

* Expanded ITS register handling and the userspace ABI: serialise
  register access, support 32-bit accesses to 64-bit registers, and
  validate restoration of IDR0-IDR2 and READ_EVENT_DATAR while keeping
  them read-only to the guest.

* Hardened direct injection teardown: track which translation owns
  forwarding, synchronise host translation restoration, and retain the
  IRQ association when a timeout requires a later retry.

* Extended selftests for register access widths, read-only behaviour,
  ID limits, malformed MSIs, and cache invalidation.

Thanks for taking the time to look at these changes!

Thanks,
Sascha

[1] https://support.arm.com/documentation/111701/latest
[2] https://linaro.atlassian.net/wiki/x/CQAF-wY
[3] https://support.arm.com/tools-and-software/fixed-virtual-platforms/arm-architecture-fvps
[4] https://lore.kernel.org/all/20261016153939.913764-1-sascha.bischoff@arm.com
[5] https://gitlab.arm.com/linux-arm/linux-sb/-/tree/gicv5_kvm_its_support_v2
[6] https://lore.kernel.org/all/20261016155741.979985-1-sascha.bischoff@arm.com/
[7] https://lore.kernel.org/all/20261102-host_gicv5_fixes-v1-0-743b61626fc5@arm.com/
[8] https://gitlab.arm.com/linux-arm/linux-sb/-/tree/gicv5_kvm_its_support_v2_with_host_fixes

Sascha Bischoff (16):
  KVM: arm64: vgic: Split out common LPI allocation
  KVM: arm64: vgic: Pass opaque device pointer to ITS MMIO callbacks
  KVM: arm64: gic-v5: Share CoreSight ID register emulation
  irqchip/gic-v5: Add ITS MMIO register definitions
  KVM: arm64: gic-v5: Add ITS device skeleton
  KVM: arm64: gic-v5: Add ITS MMIO state emulation
  KVM: arm64: gic-v5: Add ITS guest table translation emulation
  KVM: arm64: gic-v5: Add ITS translation cache maintenance
  KVM: arm64: gic-v5: Add ITS MSI injection
  KVM: arm64: gic-v5: Add ITS userspace register access
  irqchip/gic-v5: Enable direct injection in ITS
  KVM: arm64: vgic: Move direct MSI support helper to common MMIO code
  KVM: arm64: gic-v5: Implement irq forwarding
  KVM: selftests: Add VGICv5 ITS attribute tests
  KVM: selftests: Add VGICv5 ITS translation cache tests
  KVM: arm64: gic-v5: Document ITS userspace ABI

 .../virt/kvm/devices/arm-vgic-v5-its.rst      |  111 ++
 Documentation/virt/kvm/devices/index.rst      |    1 +
 arch/arm64/include/uapi/asm/kvm.h             |    2 +
 arch/arm64/kvm/Makefile                       |    1 +
 arch/arm64/kvm/arm.c                          |    6 +-
 arch/arm64/kvm/vgic/vgic-irqfd.c              |    8 +
 arch/arm64/kvm/vgic/vgic-irs-v5.c             |   75 +-
 arch/arm64/kvm/vgic/vgic-its-v5.c             | 1562 +++++++++++++++++
 arch/arm64/kvm/vgic/vgic-its.c                |  130 +-
 arch/arm64/kvm/vgic/vgic-kvm-device.c         |    4 +
 arch/arm64/kvm/vgic/vgic-mmio-v3.c            |   20 -
 arch/arm64/kvm/vgic/vgic-mmio.c               |   34 +
 arch/arm64/kvm/vgic/vgic-mmio.h               |    6 +-
 arch/arm64/kvm/vgic/vgic-v5.c                 |  182 ++
 arch/arm64/kvm/vgic/vgic.c                    |   99 ++
 arch/arm64/kvm/vgic/vgic.h                    |   20 +
 drivers/irqchip/irq-gic-v5-its.c              |  141 ++
 include/kvm/arm_vgic.h                        |  107 +-
 include/linux/irqchip/arm-gic-v5.h            |  136 +-
 include/uapi/linux/kvm.h                      |    2 +
 tools/include/uapi/linux/kvm.h                |    2 +
 tools/testing/selftests/kvm/arm64/vgic_v5.c   |  882 +++++++++-
 .../selftests/kvm/include/arm64/gic_v5.h      |   88 +
 23 files changed, 3384 insertions(+), 235 deletions(-)
 create mode 100644 Documentation/virt/kvm/devices/arm-vgic-v5-its.rst
 create mode 100644 arch/arm64/kvm/vgic/vgic-its-v5.c


base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
-- 
2.34.1




More information about the linux-arm-kernel mailing list