| 1 | .. SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | |
| 3 | iommu-testdev — IOMMU test device for bare-metal testing |
| 4 | ======================================================== |
| 5 | |
| 6 | Overview |
| 7 | -------- |
| 8 | ``iommu-testdev`` is a minimal, test-only PCI device designed to exercise |
| 9 | IOMMU translation (such as ARM SMMUv3) without requiring firmware or a guest |
| 10 | OS. Tests can populate IOMMU translation tables with known values and trigger |
| 11 | DMA operations that flow through the IOMMU translation path. It is **not** a |
| 12 | faithful PCIe endpoint and must be considered a QEMU-internal test vehicle. |
| 13 | |
| 14 | Key Features |
| 15 | ------------ |
| 16 | * **Bare-metal IOMMU testing**: No guest kernel or firmware required |
| 17 | * **Configurable DMA attributes**: Supports address space configuration via |
| 18 | MMIO registers |
| 19 | * **Deterministic verification**: Write-then-read DMA pattern with automatic |
| 20 | result checking |
| 21 | |
| 22 | Status |
| 23 | ------ |
| 24 | * Location: ``hw/misc/iommu-testdev.c`` |
| 25 | * Header: ``include/hw/misc/iommu-testdev.h`` |
| 26 | * Build guard: ``CONFIG_IOMMU_TESTDEV`` |
| 27 | |
| 28 | Device Interface |
| 29 | ---------------- |
| 30 | The device exposes a single PCI BAR0 with 32-bit MMIO registers: |
| 31 | |
| 32 | * ``ITD_REG_DMA_TRIGGERING`` (0x00): Read triggers DMA and consumes |
| 33 | the armed request |
| 34 | * ``ITD_REG_DMA_GVA_LO`` (0x04): DMA IOVA bits [31:0] |
| 35 | * ``ITD_REG_DMA_GVA_HI`` (0x08): DMA IOVA bits [63:32] |
| 36 | * ``ITD_REG_DMA_GPA_LO`` (0x1C): DMA GPA bits [31:0] for readback validation |
| 37 | * ``ITD_REG_DMA_GPA_HI`` (0x20): DMA GPA bits [63:32] for readback validation |
| 38 | * ``ITD_REG_DMA_LEN`` (0x0C): DMA transfer length |
| 39 | * ``ITD_REG_DMA_RESULT`` (0x10): DMA result |
| 40 | (0=success, 0xffffffff=idle, 0xfffffffe=armed) |
| 41 | * ``ITD_REG_DMA_DBELL`` (0x14): Write 1 to arm DMA, write 0 to disarm. |
| 42 | Arming only marks the request and sets BUSY (no latch/check), but it |
| 43 | provides an explicit gate for qtests and leaves room for async/latching. |
| 44 | * ``ITD_REG_DMA_ATTRS`` (0x18): DMA attributes which shadow some fields in |
| 45 | MemTxAttrs: |
| 46 | |
| 47 | - bit[0]: secure (1=Secure, 0=Non-Secure) |
| 48 | - bits[2:1]: ArmSecuritySpace (0=Secure, 1=Non-Secure) |
| 49 | - bit[3]: space_valid (1=space is valid, 0=ignore space and default to Non-Secure) |
| 50 | ``space`` field in MemTxAttrs is consumed only when ``space_valid`` is set. |
| 51 | For Secure/Non-Secure, ``secure`` and ``space`` must match; mismatches |
| 52 | return ``ITD_DMA_ERR_BAD_ATTRS``. Other bits are reserved but can be wired |
| 53 | up easily if future tests need to pass extra attributes. |
| 54 | |
| 55 | Translation Setup Workflow |
| 56 | -------------------------- |
| 57 | ``iommu-testdev`` never builds SMMU/AMD-Vi/RISC-V IOMMU structures on its own. |
| 58 | Architecture-specific construction lives entirely in qtest/libqos helpers. |
| 59 | Those helpers populate guest memory with page tables/architecture-specific |
| 60 | structures and program the emulated IOMMU registers directly. See the |
| 61 | ``qsmmu_setup_and_enable_translation()`` function in |
| 62 | ``tests/qtest/libqos/qos-smmuv3.c`` for an example of how SMMUv3 translation |
| 63 | is set up for this device. |
| 64 | |
| 65 | DMA Operation Flow |
| 66 | ------------------ |
| 67 | Arming semantics: |
| 68 | |
| 69 | * Writing ``DMA_DBELL`` with bit0=1 marks the request armed and sets |
| 70 | ``DMA_RESULT`` to BUSY. It does not latch GVA/LEN/ATTRS; values are sampled |
| 71 | when ``DMA_TRIGGERING`` is read. |
| 72 | * Writing ``DMA_DBELL`` with bit0=0 disarms the request and sets |
| 73 | ``DMA_RESULT`` to IDLE. |
| 74 | * Reading ``DMA_TRIGGERING`` consumes the armed request and clears the armed |
| 75 | state, even on error. |
| 76 | |
| 77 | The flow would be split into these steps, mainly for timing control and |
| 78 | debuggability: qtests can easily exercise and assert distinct paths |
| 79 | (NOT_ARMED, BAD_LEN, TX/RD failures, mismatch) instead of having all side |
| 80 | effects hidden behind a single step: |
| 81 | 1. Test programs IOMMU translation tables |
| 82 | 2. Test configures DMA IOVA (GVA_LO/HI), GPA for readback, length, and attributes |
| 83 | 3. Test writes 1 to DMA_DBELL to arm the operation |
| 84 | 4. Test reads DMA_TRIGGERING to execute DMA |
| 85 | 5. Test polls DMA_RESULT: |
| 86 | |
| 87 | - 0x00000000: Success |
| 88 | - 0xFFFFFFFE: Armed (waiting for trigger). DMA runs synchronously, so |
| 89 | BUSY is not observed once the trigger read completes. |
| 90 | - 0xDEAD0006: Bad attrs (secure/space mismatch for S/NS) |
| 91 | - 0xDEAD000X: Various error codes |
| 92 | |
| 93 | The device performs a write-then-read sequence using a known pattern |
| 94 | (0x12345678) and verifies data integrity automatically. |
| 95 | |
| 96 | Running the qtest |
| 97 | ----------------- |
| 98 | The SMMUv3 test suite uses this device and covers multiple translation modes:: |
| 99 | |
| 100 | cd build |
| 101 | QTEST_QEMU_BINARY=./qemu-system-aarch64 \\ |
| 102 | ./tests/qtest/iommu-smmuv3-test --tap -k |
| 103 | |
| 104 | This test suite exercises: |
| 105 | |
| 106 | * Stage 1 only translation |
| 107 | * Stage 2 only translation |
| 108 | * Nested (Stage 1 + Stage 2) translation |
| 109 | |
| 110 | Instantiation |
| 111 | ------------- |
| 112 | The device is not wired into any board by default. Tests instantiate it |
| 113 | via QEMU command line:: |
| 114 | |
| 115 | -device iommu-testdev |
| 116 | |
| 117 | For ARM platforms with SMMUv3:: |
| 118 | |
| 119 | -M virt,iommu=smmuv3 -device iommu-testdev |
| 120 | |
| 121 | When the IOMMU sits on the same PCI root complex (``pci.0``), the device is |
| 122 | placed behind it automatically. For other PCI topologies, specify the bus |
| 123 | explicitly. |
| 124 | |
| 125 | Limitations |
| 126 | ----------- |
| 127 | * No realistic PCIe enumeration, MSI/MSI-X, or interrupt handling |
| 128 | * No ATS/PRI support |
| 129 | * No actual device functionality beyond DMA test pattern |
| 130 | * Test-only; not suitable for production or machine realism |
| 131 | * Address space support (Secure/Root/Realm) is architecture-dependent and |
| 132 | gated by ``space_valid`` |
| 133 | * Readback uses the programmed GPA and reads via system memory, avoiding a |
| 134 | second IOMMU access for the readback step |
| 135 | |
| 136 | See also |
| 137 | -------- |
| 138 | * ``tests/qtest/iommu-smmuv3-test.c`` — SMMUv3 test suite |
| 139 | * ``tests/qtest/libqos/qos-smmuv3.{c,h}`` — SMMUv3 test library |
| 140 | * SMMUv3 emulation: ``hw/arm/smmu*`` |