[PATCH v5 00/36] KVM: arm64: Introduce vGIC-v5 with PPI support

Sascha Bischoff Sascha.Bischoff at arm.com
Thu Feb 26 07:55:21 PST 2026


This is v5 of the patch series to add the virtual GICv5 [1] device
(vgic_v5). Only PPIs are supported by this initial series, and the
vgic_v5 implementation is restricted to the CPU interface,
only. Further patch series are to follow in due course, and will add
support for SPIs, LPIs, the GICv5 IRS, and the GICv5 ITS.

v1, v2, v3, and v4 of this series can be found at [2], [3], [4], [5],
respectively.

Main changes since v4:

* Split out host capabilities from guest configuration by adding
  vgic_host_has_gicvX() for GICv3 and GICv5.

* Updated the GICv5 trap handlers to check for FEAT_GCIE in the ID
  registers, rather than checking the vgic model. This matches the
  GICv3 behaviour.

* Reworked the system register sanitisation to expose FEAT_GCIE in the
  ID registers if the host supports it. Once an irqchip is created the
  fields corresponding to othrr irqchips are zeroed. Twice. Once when
  the irqchip is created, and a second time in kvm_finalize_sys_regs()
  to work around QEMU restoring illegal state combinations to the
  system registers.

  This is ugly, but needs to be done to keep "legacy" (GICv3)
  QEMU-based VMs running without modification on GICv5 hardware. See
  "KVM: arm64: gic-v5: Sanitize ID_AA64PFR2_EL1.GCIE" for more
  details.

* Limited GICv5 VM support to 16 bits of ID space for SPIs and LPIs
  (realistically, only LPIs). Previously, we matched the host, which
  would have limited migration from 24-bit-capable hosts.

* Added trapping for ICC_IDR0_EL1 accesses to expose the ID bits (and
  hide whatever the host supports) and to hide FEAT_GCIE_LEGACY from
  guests.

* Renamed the no-vgic-v3 selftest to no-vgic, and extended it with
  GICv5 support.

These changes are based on v7.0-rc1. There's one additional fix
required which has been posted and pulled into fixes separately, which
can be found at [6]. I have pushed these changes (including the fix)
to a branch that can be found at [7], with the full WIP set at [8].

Thanks all for the feedback!

Sascha

[1] https://developer.arm.com/documentation/aes0070/latest
[2] https://lore.kernel.org/all/20251212152215.675767-1-sascha.bischoff@arm.com/
[3] https://lore.kernel.org/all/20251219155222.1383109-1-sascha.bischoff@arm.com/
[4] https://lore.kernel.org/all/20260109170400.1585048-1-sascha.bischoff@arm.com/
[5] https://lore.kernel.org/all/20260128175919.3828384-1-sascha.bischoff@arm.com/
[6] https://lore.kernel.org/all/20260225083130.3378490-1-sascha.bischoff@arm.com/
[7] https://gitlab.arm.com/linux-arm/linux-sb/-/tree/gicv5_ppi_support_v5
[8] https://gitlab.arm.com/linux-arm/linux-sb/-/tree/gicv5_support_wip

Sascha Bischoff (36):
  KVM: arm64: vgic-v3: Drop userspace write sanitization for
    ID_AA64PFR0.GIC on GICv5
  KVM: arm64: vgic: Rework vgic_is_v3() and add vgic_host_has_gicvX()
  KVM: arm64: Return early from kvm_finalize_sys_regs() if guest has run
  arm64/sysreg: Add remaining GICv5 ICC_ & ICH_ sysregs for KVM support
  arm64/sysreg: Add GICR CDNMIA encoding
  KVM: arm64: gic-v5: Add ARM_VGIC_V5 device to KVM headers
  KVM: arm64: gic: Introduce interrupt type helpers
  KVM: arm64: gic-v5: Add Arm copyright header
  KVM: arm64: gic-v5: Detect implemented PPIs on boot
  KVM: arm64: gic-v5: Sanitize ID_AA64PFR2_EL1.GCIE
  KVM: arm64: gic-v5: Support GICv5 FGTs & FGUs
  KVM: arm64: gic-v5: Add emulation for ICC_IAFFIDR_EL1 accesses
  KVM: arm64: gic-v5: Trap and emulate ICC_IDR0_EL1 accesses
  KVM: arm64: gic-v5: Add vgic-v5 save/restore hyp interface
  KVM: arm64: gic-v5: Implement GICv5 load/put and save/restore
  KVM: arm64: gic-v5: Implement direct injection of PPIs
  KVM: arm64: gic-v5: Finalize GICv5 PPIs and generate mask
  KVM: arm64: gic: Introduce queue_irq_unlock to irq_ops
  KVM: arm64: gic-v5: Implement PPI interrupt injection
  KVM: arm64: gic-v5: Init Private IRQs (PPIs) for GICv5
  KVM: arm64: gic-v5: Check for pending PPIs
  KVM: arm64: gic-v5: Trap and mask guest ICC_PPI_ENABLERx_EL1 writes
  KVM: arm64: gic-v5: Support GICv5 interrupts with KVM_IRQ_LINE
  KVM: arm64: gic-v5: Create and initialise vgic_v5
  KVM: arm64: gic-v5: Initialise ID and priority bits when resetting
    vcpu
  KVM: arm64: gic-v5: Enlighten arch timer for GICv5
  KVM: arm64: gic-v5: Mandate architected PPI for PMU emulation on GICv5
  KVM: arm64: gic: Hide GICv5 for protected guests
  KVM: arm64: gic-v5: Hide FEAT_GCIE from NV GICv5 guests
  KVM: arm64: gic-v5: Introduce kvm_arm_vgic_v5_ops and register them
  KVM: arm64: gic-v5: Set ICH_VCTLR_EL2.En on boot
  KVM: arm64: gic-v5: Probe for GICv5 device
  Documentation: KVM: Introduce documentation for VGICv5
  KVM: arm64: selftests: Introduce a minimal GICv5 PPI selftest
  KVM: arm64: gic-v5: Communicate userspace-driveable PPIs via a UAPI
  KVM: arm64: selftests: Add no-vgic-v5 selftest

 Documentation/virt/kvm/api.rst                |   6 +-
 .../virt/kvm/devices/arm-vgic-v5.rst          |  50 ++
 Documentation/virt/kvm/devices/index.rst      |   1 +
 Documentation/virt/kvm/devices/vcpu.rst       |   5 +-
 arch/arm64/include/asm/el2_setup.h            |   2 +
 arch/arm64/include/asm/kvm_asm.h              |   4 +
 arch/arm64/include/asm/kvm_host.h             |  34 ++
 arch/arm64/include/asm/kvm_hyp.h              |   9 +
 arch/arm64/include/asm/sysreg.h               |   7 +
 arch/arm64/include/asm/vncr_mapping.h         |   3 +
 arch/arm64/include/uapi/asm/kvm.h             |   1 +
 arch/arm64/kvm/arch_timer.c                   | 118 +++-
 arch/arm64/kvm/arm.c                          |  40 +-
 arch/arm64/kvm/config.c                       | 123 +++-
 arch/arm64/kvm/emulate-nested.c               |  68 +++
 arch/arm64/kvm/hyp/include/hyp/switch.h       |  27 +
 arch/arm64/kvm/hyp/nvhe/Makefile              |   2 +-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  32 ++
 arch/arm64/kvm/hyp/nvhe/switch.c              |  15 +
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            |   8 +
 arch/arm64/kvm/hyp/vgic-v5-sr.c               | 120 ++++
 arch/arm64/kvm/hyp/vhe/Makefile               |   2 +-
 arch/arm64/kvm/nested.c                       |   5 +
 arch/arm64/kvm/pmu-emul.c                     |  20 +-
 arch/arm64/kvm/sys_regs.c                     | 175 +++++-
 arch/arm64/kvm/vgic/vgic-init.c               | 151 +++--
 arch/arm64/kvm/vgic/vgic-kvm-device.c         | 100 +++-
 arch/arm64/kvm/vgic/vgic-mmio.c               |  28 +-
 arch/arm64/kvm/vgic/vgic-v3.c                 |   2 +-
 arch/arm64/kvm/vgic/vgic-v5.c                 | 531 +++++++++++++++++-
 arch/arm64/kvm/vgic/vgic.c                    | 106 +++-
 arch/arm64/kvm/vgic/vgic.h                    |  59 +-
 arch/arm64/tools/sysreg                       | 480 ++++++++++++++++
 include/kvm/arm_arch_timer.h                  |  11 +-
 include/kvm/arm_pmu.h                         |   5 +-
 include/kvm/arm_vgic.h                        | 143 ++++-
 include/linux/irqchip/arm-gic-v5.h            |  35 ++
 include/linux/kvm_host.h                      |   1 +
 include/uapi/linux/kvm.h                      |   2 +
 tools/arch/arm64/include/uapi/asm/kvm.h       |   1 +
 tools/include/uapi/linux/kvm.h                |   2 +
 tools/testing/selftests/kvm/Makefile.kvm      |   3 +-
 .../testing/selftests/kvm/arm64/no-vgic-v3.c  | 177 ------
 tools/testing/selftests/kvm/arm64/no-vgic.c   | 297 ++++++++++
 tools/testing/selftests/kvm/arm64/vgic_v5.c   | 219 ++++++++
 .../selftests/kvm/include/arm64/gic_v5.h      | 148 +++++
 46 files changed, 3026 insertions(+), 352 deletions(-)
 create mode 100644 Documentation/virt/kvm/devices/arm-vgic-v5.rst
 create mode 100644 arch/arm64/kvm/hyp/vgic-v5-sr.c
 delete mode 100644 tools/testing/selftests/kvm/arm64/no-vgic-v3.c
 create mode 100644 tools/testing/selftests/kvm/arm64/no-vgic.c
 create mode 100644 tools/testing/selftests/kvm/arm64/vgic_v5.c
 create mode 100644 tools/testing/selftests/kvm/include/arm64/gic_v5.h

-- 
2.34.1



More information about the linux-arm-kernel mailing list