PUBLIC ARCHITECTURE / ENGINEERING REFERENCE
AMD IOMMU: the engineering reference
Alignment, lookup structures, command completion and GA records—connected to the working lab.
What claims does this page make? 3 points
- Spec rule: the GA log entry layout, GALogLen sizes, register offsets and the §2.7.4 restart steps come from AMD IOMMU Specification 48882 rev 3.11.
- Platform assumption: which host Modes, physical-address widths and optional features exist depends on the IOMMU's capability bits and the Linux driver.
- Teaching model: one host leaf per context, 52-bit addresses and a four-level guest walk are choices of this site's lab, not AMD guarantees.
Alignment: frames versus requests
The leaf size defines the frame boundary. A 2 MiB frame must begin at a multiple of 2 MiB; 4 KiB alignment alone is insufficient. Alignment is a minimum boundary requirement, not a maximum. A 1 GiB-aligned address also satisfies the smaller alignments.
Swipe or scroll horizontally to see every column.
| Leaf size | AMD lab leaf level | Frame mask / zero bits | Valid offset |
|---|---|---|---|
| 4 KiB | L1 | 0xFFF / low 12 | 0x000–0xFFF |
| 2 MiB | L2 | 0x1FFFFF / low 21 | 0x000000–0x1FFFFF |
| 1 GiB | L3 | 0x3FFFFFFF / low 30 | 0x00000000–0x3FFFFFFF |
Check base % pageSize == 0. Translation preserves
address % pageSize and combines it with the mapped base.
For example, a request at 0x1234 can address byte
0x234 in a 4 KiB page. Rejecting this request merely
because it is not 4 KiB aligned would break ordinary byte-addressed
DMA.
Page-table allocations in this teaching model are 4 KiB aligned and contain 512 eight-byte entries. A table pointer and a large data-frame pointer have different alignment rules. Entry addresses themselves advance by eight bytes. Hardware physical-address width, supported formats and permissions remain separate checks.
Swipe or scroll horizontally to see every column.
| Mode | GPA base control | SPA base control |
|---|---|---|
| Nested | Guest leaf size | Host leaf size |
| Guest Only | Unused | Guest leaf size; GPA = SPA |
| Host Only | Host leaf size | Host leaf size |
Mixed sizes: work through the offset twice
Choose a 4 KiB guest leaf at GPA 0x801000, a 2 MiB host
frame at SPA 0x12000000, and guest offset
0xABC. The guest result is 0x801ABC. Its
host page starts at 0x800000; the host offset is
0x1ABC. The final address is 0x12001ABC.
Requiring the guest base itself to align to 2 MiB would incorrectly
reject this valid mapping.
The lab allocates one host data leaf per context. When the host leaf is smaller than the guest leaf, only the host slice containing the configured guest address is mapped. A request outside that slice can fault even while remaining inside the guest page. When the host leaf is larger, its whole source interval must avoid the synthetic table allocations. These allocation limits belong to this example, not to AMD hardware.
Try the alignment controls. “Align entered bases” rounds down explicitly; Apply validates before replacing the active mapping.
Device, process and page entries
Swipe or scroll horizontally to see every column.
| Structure | Selected fields / role | What to verify |
|---|---|---|
| Device table entry (DTE), 32 bytes | DeviceID selects a device record; V, TV, GV, host Mode/root, DomainID, permissions, GLX/GCR3 and interrupt controls govern separate functions. | Valid encoding, supported capabilities, address width, permissions and cache invalidation after updates. |
| GCR3 hierarchy | PASID selects the guest root using GLX levels. Subordinate GCR3 pointers and guest-table fetches participate in the configured address spaces. | Correct PASID and width; valid pointers; host mappings for nested table fetches. GCR3 is not the final data address. A GCR3 leaf can select the same guest root GPA as CPU CR3, with separate cache maintenance. Run the shared CPU/device table lesson. |
| Guest page entry | x86-style guest table/page fields; guest root → guest leaf → GPA. | Canonical address, P/presence, write permission at each traversed level and large-page frame alignment. |
| Host page entry, v1 format | PR/presence, IR/IW permissions, target address and NextLevel; leaf maps GPA to SPA. | Configured root Mode, valid level transitions and zero address bits for skipped levels. A skipped level is not a wildcard. |
| Interrupt-remapping entry (IRTE) | Interrupt table selected by the DTE; remapping/guest format controls vector delivery. | Validate the interrupt format independently from the DMA translation path. An IRTE is neither a page entry nor a GA log record. |
The raw DTE inspector and downloadable C++ expose the subset actually constructed by this lab. Host Mode 1–6 is configurable; real availability depends on the IOMMU capabilities, including supported host address-translation size. Guest Only selects host Mode 0 in this lesson. The model uses a four-level guest walk and caps physical addresses at 52 bits; neither value is a universal platform guarantee.
GLX and the device PASID capability are independent limits. This UI enforces the smaller capacity to prevent aliasing. A rejected UI configuration is a software guard, not a fabricated architectural event. DomainID identifies an IOMMU translation domain; DeviceID identifies a requester; PASID identifies a process address space. They are not interchangeable.
Read and write permissions are checked through the selected walks. Full execute/privilege semantics, accessed/dirty updates, atomic table changes, encrypted-memory ownership and every reserved-bit rule are outside the DMA lab’s model. The reference names them so a working demo is not mistaken for complete validation. dmakit, the executable AMD model behind the Linux DMA code lab, does update the host Accessed and Dirty bits and check each device access against the SEV-SNP RMP; it is not complete validation either.
Commands, events, PPR and GA are separate formats
Swipe or scroll horizontally to see every column.
| Family | Bytes per entry | Types relevant to the lab | Consumer action |
|---|---|---|---|
| Command buffer | 16 | COMPLETION_WAIT; INVALIDATE_DEVTAB_ENTRY; INVALIDATE_IOMMU_PAGES; INVALIDATE_IOTLB_PAGES; INVALIDATE_INTERRUPT_TABLE; COMPLETE_PPR_REQUEST. Optional commands require capability checks. | IOMMU fetches software commands. Head advance is not completion of their effects. |
| Event log | 16 | ILLEGAL_DEV_TABLE_ENTRY; IO_PAGE_FAULT; DEV_TAB_HARDWARE_ERROR; PAGE_TAB_HARDWARE_ERROR; ILLEGAL_COMMAND_ERROR; COMMAND_HARDWARE_ERROR; IOTLB_INV_TIMEOUT; INVALID_DEVICE_REQUEST; INVALID_PPR_REQUEST. | Software diagnoses the record, resolves the cause where possible and separately decides whether to retry. |
| PPR log | 16 | PAGE_SERVICE_REQUEST, PPRCode 1. Device/process context, requested page/access and group information support PRI service. | Software handles the request and responds through COMPLETE_PPR_REQUEST. A response is not another PPR-log entry. |
| GA log | 8 | GA_GUEST_NR, opcode 1, in revision 3.11. Written only for a non-running guest when the IRTE's GALogIntr is set and the GA log is enabled (GALogEn) and has room; otherwise no entry. | Software uses the DeviceID and tag to handle a guest-not-running notification. No DMA repair or EOI is implied. |
Identical numeric codes in different record families have different meanings. Decode using the buffer type before interpreting the opcode. The event catalogue is the baseline set used in the companion lesson; the feature-dependent EVENT_COUNTER_ZERO, GUEST_EVENT_FAULT, VIOMMU_HARDWARE_ERROR, RMP_PAGE_FAULT and RMP_HARDWARE_ERROR records also appear in §2.5. Their fields and recovery paths must be interpreted using the corresponding feature definitions. They are not injected by this baseline lab.
Command sequencing and fault diagnosis have interactive examples. Selected memory-fault words and the GA codec are packed encodings; most displayed ring records remain semantic teaching records.
Safe mapping changes and PCIe requests
- Gate affected DMA and retain ownership of the old backing memory while requests can still use it.
- Publish valid new table/configuration contents with the platform’s required coherency and ordering operations.
- Invalidate the appropriate IOMMU state. If the device holds ATS translations, invalidate its ATC as well and account for acknowledgments.
- Observe command completion before reusing old memory or permitting a fresh translation and retry.
PCIe ATS obtains translation and permissions; PRI requests software service when necessary. Neither is a byte-copy operation. The NIC must advertise and enable the relevant features, and Bus Master Enable gates memory traffic. An untranslated rejected request, an unsuccessful ATS lookup and a page-service request have different reporting paths. Ordinary AT=10 traffic relies on a trusted device using its ATS result: §2.11 states that the IOMMU checks translated-request authorization but does not revalidate the SPA. Secure ATS instead returns a GPA and applies inline host translation. The mock’s provenance guard is a stricter teaching constraint.
The mock NIC is an intentionally small Ethernet descriptor model, not a vendor register set or a complete PCIe TLP engine. Splitting transfers at a mapped boundary, preventing bytes from the failing page, and preserving already completed bytes are the behaviours under test.
GA entries, control registers and recovery
“GA entry” is ambiguous. The interrupt-remapping table can contain a guest-capable IRTE; the guest APIC backing page stores pending interrupt state; the GA log contains notifications for software. These are three different structures. The lab’s basic interrupt remapper models a legacy entry, while the buffer page separately illustrates a guest virtual interrupt.
Swipe or scroll horizontally to see every column.
| Bits in 64-bit word | Dword / bits | Meaning |
|---|---|---|
| 63:60 | +4 / 31:28 | Opcode = 1 (GA_GUEST_NR) |
| 59:48 | +4 / 27:16 | Reserved; encode zero |
| 47:32 | +4 / 15:0 | DeviceID, 16 bits |
| 31:0 | +0 / 31:0 | GATag, 32-bit software value from the IRTE |
Example: DeviceID 0x0200, GATag 0x1234 →
word 0x1000020000001234 → memory bytes
34 12 00 00 00 02 00 10. The vector is not encoded in
this log entry. Revision 3.11 specifies one GA log opcode here; other
opcode values must not be presented as invented GA types.
Encode and decode a record.
The guest-capable IRTE includes controls such as GuestMode, IsRun and GALogIntr, as well as the guest APIC backing-page reference and tag. Guest-capable 128-bit IRTE formats differ from the legacy 32-bit format; select and validate them according to the enabled GA/GAM and other capabilities. With an eligible interrupt and a non-running guest, pending state is recorded in the backing page and enabled GA logging notifies the hypervisor. A running guest uses the applicable delivery path instead. Consuming a notification does not service the vector.
Swipe or scroll horizontally to see every column.
| Register / offset | Fields | Engineering interpretation |
|---|---|---|
| Control / 0x0018 | GAEn [17]; GALogEn [28]; GAIntEn [29] | Feature, logging and log-notification interrupt enable are separate controls. Check GASup before enabling the feature. |
| GA log base / 0x00E0 | GALogBase [51:12]; GALogLen [59:56] | Base is 4 KiB aligned. Len 8–12 selects 512–8192 entries (4–64 KiB). Other encodings are reserved in rev 3.11. |
| GA shadow-tail address / 0x00E8 | GATAddr [51:3] | 8-byte-aligned SPA of a tail-pointer copy in memory. Zero disables the copy. This is not the Tail offset register. |
| GA Head / 0x2040; Tail / 0x2048 | Byte offsets, advancing by 8 | Software consumes with Head; IOMMU produces with Tail. Reserve one slot to distinguish full from empty. |
| Status / 0x2020 | GALogRun [8]; GALOverflow [9]; GAInt [10] | Run is read-only; overflow and notification are write-one-to-clear. Acknowledging notification does not repair overflow. |
Length trap: GA has eight-byte records but
GALogLen=8 still allocates 4 KiB:
entries = 2^(Len+1). Do not reuse the command buffer’s
entry-count formula for GA. The eight-slot illustrations are
intentionally small and are not legal hardware allocations.
After overflow
Preserve available records and follow §2.7.4: wait for GALogRun=0; disable GALogEn; adjust the allocation and Head/Tail only while stopped; clear GALOverflow with W1C; then re-enable logging and configure GAIntEn. Reconcile pending guest interrupt state because lost notifications cannot be recovered by moving a pointer. Restarting the log neither replays lost entries nor completes guest EOI. The mini-lab stops at its capacity boundary instead of emulating all overflow races.
Run fault injection, all ten commands and buffer lifecycle tests →
48882 coverage map and implementation boundary
Swipe or scroll horizontally to see every column.
| Spec area | Where this site covers it | Boundary |
|---|---|---|
| Device tables, translation and protection (§2.1–2.2) | DMA lab: DTE words, PASID/GCR3, guest/host walks, alignment and permission faults. | DMA lab: selected v1 host and four-level guest semantics; no full v2 page format or hardware capability enumeration. dmakit translates through v2 page tables. |
| Interrupt remapping (§2.2.5) | Basic IRTE demo; GA explanation and virtual interrupt lifecycle. | No complete MSI/MSI-X packet decoder. The basic demo has no x2APIC/AVIC engine or guest-capable IRTE executor; dmakit models 128-bit IRTEs, x2APIC destinations and guest virtual APIC delivery with the GA log. |
| Initialization (§2.3) | Discover capabilities, allocate tables and queues, establish mappings, then enable the supported facilities in the specified order. | Reference only; the website does not discover, configure or reset real hardware. |
| Commands (§2.4) | Command catalogue and invalidation/completion lesson. | No real DMA coherency, concurrent hardware execution or exhaustive command-word encoder. |
| Events, PPR, GA (§2.5–2.7) | Fault catalogue, PRI response lifecycle, GA codec and log ownership. | The engineering lab’s dual logs are a reduced teaching model without the early-overflow warning; dmakit models dual Event and PPR logs with auto-swap, PPR auto response and the PPR early-overflow warning. No platform recovery implementation. |
| IOMMU interrupts (§2.8) | Separate notification, cause repair and guest ISR/EOI. | No physical interrupt controller, affinity management or interrupt-remapping driver. |
| Registers / capabilities (Chapter 3) | Base/length and Head/Tail calculator; GA controls above; raw DTE inspector. | No real MMIO: dmakit emulates the IOMMU’s registers in software. Capability-specific reserved encodings must be checked on the target platform. |
| System integration and optional facilities | Public spec for IVRS/platform discovery, exclusion ranges, virtualized IOMMU, performance counters, MARC, SEV-SNP/RMP and feature-specific extensions. | Covered in the revision 3.11 specification map, including CXL and SEV-TIO. These optional facilities are reference content, except SEV-SNP: dmakit checks device accesses against the RMP and models Secure ATS (secure DMA). |
Use the same test scenario vocabulary across implementations—requester, address space, input address, access, result and evidence—but keep architecture-specific encoders separate. A passing educational test proves its stated assertion; it does not establish whole-spec conformance.
Sources and revision
Reference baseline: the April 2026 rev 3.11 PDF; AMD IOMMU Specification 48882, revision 3.11, April 2026, especially §§2.4–2.7 and the MMIO register definitions. The link opens AMD's own PDF. All examples on this page are independently written.
Implementation cross-check: Linux AMD IOMMU types and driver sources. Driver implementations are useful evidence, but capability-dependent architectural rules come from the specification.