요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=================
x86 IOMMU Support
=================
The architecture specs can be obtained from the below locations.
- Intel: http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/vt-directed-io-spec.pdf
- AMD: https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/specifications/48882_3_07_PUB.pdf
This guide gives a quick cheat sheet for some basic understanding.
Basic stuff
-----------
ACPI enumerates and lists the different IOMMUs on the platform, and
device scope relationships between devices and which IOMMU controls
them.
Some ACPI Keywords:
- DMAR - Intel DMA Remapping table
- DRHD - Intel DMA Remapping Hardware Unit Definition
- RMRR - Intel Reserved Memory Region Reporting Structure
- IVRS - AMD I/O Virtualization Reporting Structure
- IVDB - AMD I/O Virtualization Definition Block
- IVHD - AMD I/O Virtualization Hardware Definition
What is Intel RMRR?
^^^^^^^^^^^^^^^^^^^
There are some devices the BIOS controls, for e.g USB devices to perform
PS2 emulation. The regions of memory used for these devices are marked
reserved in the e820 map. When we turn on DMA translation, DMA to those
regions will fail. Hence BIOS uses RMRR to specify these regions along with
devices that need to access these regions. OS is expected to setup
unity mappings for these regions for these devices to access these regions.
What is AMD IVRS?
^^^^^^^^^^^^^^^^^
The architecture defines an ACPI-compatible data structure called an I/O
Virtualization Reporting Structure (IVRS) that is used to convey information
related to I/O virtualization to system software. The IVRS describes the
configuration and capabilities of the IOMMUs contained in the platform as
well as information about the devices that each IOMMU virtualizes.
The IVRS provides information about the following:
- IOMMUs present in the platform including their capabilities and proper configuration
- System I/O topology relevant to each IOMMU
- Peripheral devices that cannot be otherwise enumerated
- Memory regions used by SMI/SMM, platform firmware, and platform hardware. These are generally exclusion ranges to be configured by system software.
How is an I/O Virtual Address (IOVA) generated?
-----------------------------------------------
Well behaved drivers call dma_map_*() calls before sending command to device
that needs to perform DMA. Once DMA is completed and mapping is no longer
required, driver performs dma_unmap_*() calls to unmap the region.
Intel Specific Notes
--------------------
Graphics Problems?
^^^^^^^^^^^^^^^^^^
If you encounter issues with graphics devices, you can try adding
option intel_iommu=igfx_off to turn off the integrated graphics engine.
If this fixes anything, please ensure you file a bug reporting the problem.
Some exceptions to IOVA
^^^^^^^^^^^^^^^^^^^^^^^
Interrupt ranges are not address translated, (0xfee00000 - 0xfeefffff).
The same is true for peer to peer transactions. Hence we reserve the
address from PCI MMIO ranges so they are not allocated for IOVA addresses.
AMD Specific Notes
------------------
Graphics Problems?
^^^^^^^^^^^^^^^^^^
If you encounter issues with integrated graphics devices, you can try adding
option iommu=pt to the kernel command line use a 1:1 mapping for the IOMMU. If
this fixes anything, please ensure you file a bug reporting the problem.
Fault reporting
---------------
When errors are reported, the IOMMU signals via an interrupt. The fault
reason and device that caused it is printed on the console.
Kernel Log Samples
------------------
Intel Boot Messages
^^^^^^^^^^^^^^^^^^^
Something like this gets printed indicating presence of DMAR tables
in ACPI:
::
ACPI: DMAR (v001 A M I OEMDMAR 0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0
When DMAR is being processed and initialized by ACPI, prints DMAR locations
and any RMRR's processed:
::
ACPI DMAR:Host address width 36
ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed91000
ACPI DMAR:DRHD (flags: 0x00000001)base: 0x00000000fed93000
ACPI DMAR:RMRR base: 0x00000000000ed000 end: 0x00000000000effff
ACPI DMAR:RMRR base: 0x000000007f600000 end: 0x000000007fffffff
When DMAR is enabled for use, you will notice:
::
PCI-DMA: Using DMAR IOMMU
Intel Fault reporting
^^^^^^^^^^^^^^^^^^^^^
::
DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
DMAR:[fault reason 05] PTE Write access is not set
DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
DMAR:[fault reason 05] PTE Write access is not set
AMD Boot Messages
^^^^^^^^^^^^^^^^^
Something like this gets printed indicating presence of the IOMMU:
::
iommu: Default domain type: Translated
iommu: DMA domain TLB invalidation policy: lazy mode
AMD Fault reporting
^^^^^^^^^^^^^^^^^^^
::
AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0007 address=0xffffc02000 flags=0x0000]
AMD-Vi: Event logged [IO_PAGE_FAULT device=07:00.0 domain=0x0007 address=0xffffc02000 flags=0x0000]
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
x86 IOMMU 지원과 ACPI 기본 용어
1-27x86 IOMMU 아키텍처 사양은 Intel의 `http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/vt-directed-io-spec.pdf`와 AMD의 `https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/specifications/48882_3_07_PUB.pdf`에서 구할 수 있습니다. 이 문서는 기본 개념을 빠르게 확인하기 위한 요약 안내서입니다.
ACPI는 platform에 있는 여러 IOMMU를 열거하고, 각 device와 이를 제어하는 IOMMU 사이의 device scope 관계를 나열합니다.
자주 쓰이는 ACPI keyword는 다음과 같습니다.
- `DMAR`: Intel DMA Remapping table
- `DRHD`: Intel DMA Remapping Hardware Unit Definition
- `RMRR`: Intel Reserved Memory Region Reporting Structure
- `IVRS`: AMD I/O Virtualization Reporting Structure
- `IVDB`: AMD I/O Virtualization Definition Block
- `IVHD`: AMD I/O Virtualization Hardware Definition
Intel RMRR와 AMD IVRS
28-53BIOS가 제어하는 device가 있습니다. 예를 들어 USB device를 이용해 PS2 emulation을 수행할 수 있습니다. 이 device들이 사용하는 memory region은 e820 map에서 reserved로 표시됩니다. DMA translation을 켜면 이 region을 향한 DMA가 실패하므로, BIOS는 RMRR로 해당 region과 그곳에 접근해야 하는 device를 함께 지정합니다. OS는 이 device가 region에 접근할 수 있도록 해당 범위에 unity mapping을 설정해야 합니다.
AMD 아키텍처는 I/O virtualization 관련 정보를 system software에 전달하기 위해 ACPI 호환 data structure인 I/O Virtualization Reporting Structure(IVRS)를 정의합니다. IVRS는 platform에 포함된 IOMMU의 configuration과 capability, 그리고 각 IOMMU가 virtualize하는 device 정보를 설명합니다.
IVRS가 제공하는 정보는 다음과 같습니다.
- platform에 존재하는 IOMMU와 그 capability 및 올바른 configuration
- 각 IOMMU와 관련된 system I/O topology
- 다른 방법으로는 열거할 수 없는 peripheral device
- SMI/SMM, platform firmware, platform hardware가 사용하는 memory region. 일반적으로 system software가 설정해야 하는 exclusion range입니다.
IOVA 생성과 Intel 관련 예외
54-77올바르게 동작하는 driver는 DMA를 수행할 device에 command를 보내기 전에 `dma_map_*()` 계열 함수를 호출합니다. DMA가 끝나 mapping이 더 이상 필요하지 않으면 `dma_unmap_*()` 계열 함수를 호출해 region의 mapping을 해제합니다. 이 과정에서 I/O Virtual Address(IOVA)가 만들어지고 회수됩니다.
Intel integrated graphics device에서 문제가 발생하면 `intel_iommu=igfx_off` option을 추가해 integrated graphics engine을 끄는 방법을 시험할 수 있습니다. 이 조치로 문제가 해결되더라도 원인을 고칠 수 있도록 반드시 bug를 보고해야 합니다.
interrupt range `0xfee00000-0xfeefffff`는 address translation을 거치지 않습니다. peer-to-peer transaction도 마찬가지입니다. 따라서 이 주소들이 IOVA로 할당되지 않도록 PCI MMIO range에서 예약합니다.
AMD passthrough와 fault 보고
78-93AMD integrated graphics device에서 문제가 발생하면 kernel command line에 `iommu=pt`를 추가해 IOMMU에 1:1 mapping을 사용하도록 시험할 수 있습니다. 이 설정으로 문제가 해결되면 반드시 bug를 보고해야 합니다.
오류가 발생하면 IOMMU는 interrupt로 이를 알립니다. fault의 원인과 fault를 일으킨 device가 console에 출력됩니다.
Intel boot message 예시
94-124ACPI에 DMAR table이 있으면 다음과 비슷한 message가 출력됩니다.
ACPI: DMAR (v001 A M I OEMDMAR 0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0
ACPI가 DMAR을 처리하고 초기화할 때는 DMAR 위치와 처리한 RMRR이 출력됩니다.
ACPI DMAR:Host address width 36
ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed91000
ACPI DMAR:DRHD (flags: 0x00000001)base: 0x00000000fed93000
ACPI DMAR:RMRR base: 0x00000000000ed000 end: 0x00000000000effff
ACPI DMAR:RMRR base: 0x000000007f600000 end: 0x000000007fffffff
DMAR이 실제로 활성화되면 다음 message를 볼 수 있습니다.
PCI-DMA: Using DMAR IOMMU
Intel fault 보고 예시
125-134다음 예시는 device `00:02.0`의 DMA write가 PTE write permission이 없는 주소에 접근해 발생한 Intel DMAR fault입니다.
DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
DMAR:[fault reason 05] PTE Write access is not set
DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
DMAR:[fault reason 05] PTE Write access is not set
AMD boot 및 fault message 예시
135-151AMD IOMMU가 있으면 default domain type과 DMA domain TLB invalidation policy가 다음과 같이 출력될 수 있습니다.
iommu: Default domain type: Translated
iommu: DMA domain TLB invalidation policy: lazy mode
AMD fault report는 `IO_PAGE_FAULT`를 일으킨 domain, address, flag를 기록하며 device가 알려진 경우 PCI address도 함께 표시합니다.
AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0007 address=0xffffc02000 flags=0x0000]
AMD-Vi: Event logged [IO_PAGE_FAULT device=07:00.0 domain=0x0007 address=0xffffc02000 flags=0x0000]
요약과 해설
iommu.rst:1-151ACPI의 DMAR/IVRS 정보는 device를 담당하는 IOMMU와 firmware가 예약한 memory range를 OS에 전달합니다. driver는 `dma_map_*()`와 `dma_unmap_*()`으로 IOVA lifecycle을 관리하며, RMRR range에는 device가 firmware memory에 계속 접근할 수 있도록 unity mapping이 필요합니다.