[RFC PATCH v2 0/5] Add support for AMD IOMMU GAPPI

From: Sairaj Kodilkar

Date: Wed Jul 08 2026 - 05:19:00 EST


Introduction
============
On newer generations of AMD processors, the IOMMU AVIC/x2AVIC feature can be
enabled using the Guest APIC Physical Processor Interrupt (GAPPI) mode, which is
an alternative for handling AVIC guest interrupts to non-running vCPUs
(i.e., IRTE[IsRun]=0).

With GAPPI enabled, the IOMMU delivers a posted interrupt to the physical CPU
described by the IRTE destination fields, with the wake-up vector in ga_tag.

See section 2.2.5.4, Guest APIC Physical Processor Interrupt, of the AMD I/O
Virtualization Technology (IOMMU) Specification [1] for more details on GAPPI.

Implementation Details
======================
GAPPI reuses the posted-interrupt wake-up path introduced for Intel VMX: the
IOMMU sets ga_tag to POSTED_INTR_WAKEUP_VECTOR, and SVM registers the handler
with kvm_set_posted_intr_wakeup_handler().

SVM maintains a per-CPU list of vCPUs that are scheduled out. When a CPU
receives a GAPPI interrupt from the IOMMU, the handler walks that list, finds
vCPUs with a pending IRR bit, and wakes them.

The IRTE destination is chosen as the last host CPU where the vCPU ran, to
reduce unnecessary VMEXITs from GAPPI deliveries.

The first patch refactors the SVM/IOMMU interface: apicid (formerly cpu)
denotes the running vCPU's host APIC ID or, when the vCPU is scheduled out,
the APIC ID of the pCPU that hosts it on its GAPPI wake-up list. Explicit
running and posted-interrupt flags replace the old ga_log_intr boolean, since
apicid no longer implies vCPU state on its own.

Advantages
==========
With GALOG, the IOMMU can generate only a single interrupt via MMIO offset
0x180h (XT IOMMU GA Log Interrupt Control Register) and appends vCPU
information to the GALOG buffer. The hypervisor must scan this list to wake
the vCPUs, which can introduce significant latency and even cause buffer
overflows at high interrupt rates.

GAPPI avoids this problem by distributing posted interrupts across multiple
CPUs.

[1] https://docs.amd.com/v/u/en-US/48882_3.11_IOMMU_PUB

-------

Changes since V1:
https://lore.kernel.org/all/20260626105906.14577-1-sarunkod@xxxxxxx/

Patch4
- Disable interrupts while holding wakeup list lock inside [sashiko]
avic_add_vcpu_to_gappi_wakeup_list and avic_remove_vcpu_from_gappi_wakeup_list
- Unregister posted_intr_wakeup_handler during module unload [sashiko]

Patch 5
- Disable GAPPI feature during kexec and suspend path [sashiko]

-------

Sairaj Kodilkar (5):
iommu/amd: kvm/svm: Improve API between SVM and AMD IOMMU
iommu/amd: Configure IRTE to use the GAPPI for posted interrupts
kvm/svm: Introduce per-CPU lock and wakeup queue
kvm/svm: Update the per-CPU wakeup-list during vCPU load and unload
iommu/amd: Provide kernel command line option to enable GAPPI