← Documents Documentation/userspace-api/iommufd.rst GitHub 원문 ↗

Linux 6.18.37 · Userspace API

IOMMUFD

파일 디스크립터 기반 IOMMU 사용자 API의 객체 모델, 페이지 테이블 연결, 커널 구조와 VFIO 통합을 설명합니다.

Source pathDocumentation/userspace-api/iommufd.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

iommufd.rst:1-384

IOMMUFD는 `/dev/iommu` 파일 디스크립터를 중심으로 IOAS, 장치, paging·nested HWPT와 가상 IOMMU 객체를 연결해 사용자 공간 DMA를 관리하는 공통 API입니다.

문서는 객체 생성 순서, 자동·수동 domain, PFN 저장과 공유, device 중심 kernel API, VFIO 호환 경로와 향후 PASID·dirty tracking·PRI 계획을 함께 설명합니다.

한국어 전문 번역은 원문 384줄 전체와 세 ASCII 객체 관계도를 연속 좌표로 대조하고, 도식은 동일한 관계를 갖는 구조화 흐름도로 다시 구성했습니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0+
2
3 =======
4 IOMMUFD
5 =======
6
7 :Author: Jason Gunthorpe
8 :Author: Kevin Tian
9
10 Overview
11 ========
12
13 IOMMUFD is the user API to control the IOMMU subsystem as it relates to managing
14 IO page tables from userspace using file descriptors. It intends to be general
15 and consumable by any driver that wants to expose DMA to userspace. These
16 drivers are eventually expected to deprecate any internal IOMMU logic
17 they may already/historically implement (e.g. vfio_iommu_type1.c).
18
19 At minimum iommufd provides universal support of managing I/O address spaces and
20 I/O page tables for all IOMMUs, with room in the design to add non-generic
21 features to cater to specific hardware functionality.
22
23 In this context the capital letter (IOMMUFD) refers to the subsystem while the
24 small letter (iommufd) refers to the file descriptors created via /dev/iommu for
25 use by userspace.
26
27 Key Concepts
28 ============
29
30 User Visible Objects
31 --------------------
32
33 Following IOMMUFD objects are exposed to userspace:
34
35 - IOMMUFD_OBJ_IOAS, representing an I/O address space (IOAS), allowing map/unmap
36 of user space memory into ranges of I/O Virtual Address (IOVA).
37
38 The IOAS is a functional replacement for the VFIO container, and like the VFIO
39 container it copies an IOVA map to a list of iommu_domains held within it.
40
41 - IOMMUFD_OBJ_DEVICE, representing a device that is bound to iommufd by an
42 external driver.
43
44 - IOMMUFD_OBJ_HWPT_PAGING, representing an actual hardware I/O page table
45 (i.e. a single struct iommu_domain) managed by the iommu driver. "PAGING"
46 primarily indicates this type of HWPT should be linked to an IOAS. It also
47 indicates that it is backed by an iommu_domain with __IOMMU_DOMAIN_PAGING
48 feature flag. This can be either an UNMANAGED stage-1 domain for a device
49 running in the user space, or a nesting parent stage-2 domain for mappings
50 from guest-level physical addresses to host-level physical addresses.
51
52 The IOAS has a list of HWPT_PAGINGs that share the same IOVA mapping and
53 it will synchronize its mapping with each member HWPT_PAGING.
54
55 - IOMMUFD_OBJ_HWPT_NESTED, representing an actual hardware I/O page table
56 (i.e. a single struct iommu_domain) managed by user space (e.g. guest OS).
57 "NESTED" indicates that this type of HWPT should be linked to an HWPT_PAGING.
58 It also indicates that it is backed by an iommu_domain that has a type of
59 IOMMU_DOMAIN_NESTED. This must be a stage-1 domain for a device running in
60 the user space (e.g. in a guest VM enabling the IOMMU nested translation
61 feature.) As such, it must be created with a given nesting parent stage-2
62 domain to associate to. This nested stage-1 page table managed by the user
63 space usually has mappings from guest-level I/O virtual addresses to guest-
64 level physical addresses.
65
66 - IOMMUFD_FAULT, representing a software queue for an HWPT reporting IO page
67 faults using the IOMMU HW's PRI (Page Request Interface). This queue object
68 provides user space an FD to poll the page fault events and also to respond
69 to those events. A FAULT object must be created first to get a fault_id that
70 could be then used to allocate a fault-enabled HWPT via the IOMMU_HWPT_ALLOC
71 command by setting the IOMMU_HWPT_FAULT_ID_VALID bit in its flags field.
72
73 - IOMMUFD_OBJ_VIOMMU, representing a slice of the physical IOMMU instance,
74 passed to or shared with a VM. It may be some HW-accelerated virtualization
75 features and some SW resources used by the VM. For examples:
76
77 * Security namespace for guest owned ID, e.g. guest-controlled cache tags
78 * Non-device-affiliated event reporting, e.g. invalidation queue errors
79 * Access to a shareable nesting parent pagetable across physical IOMMUs
80 * Virtualization of various platforms IDs, e.g. RIDs and others
81 * Delivery of paravirtualized invalidation
82 * Direct assigned invalidation queues
83 * Direct assigned interrupts
84
85 Such a vIOMMU object generally has the access to a nesting parent pagetable
86 to support some HW-accelerated virtualization features. So, a vIOMMU object
87 must be created given a nesting parent HWPT_PAGING object, and then it would
88 encapsulate that HWPT_PAGING object. Therefore, a vIOMMU object can be used
89 to allocate an HWPT_NESTED object in place of the encapsulated HWPT_PAGING.
90
91 .. note::
92
93 The name "vIOMMU" isn't necessarily identical to a virtualized IOMMU in a
94 VM. A VM can have one giant virtualized IOMMU running on a machine having
95 multiple physical IOMMUs, in which case the VMM will dispatch the requests
96 or configurations from this single virtualized IOMMU instance to multiple
97 vIOMMU objects created for individual slices of different physical IOMMUs.
98 In other words, a vIOMMU object is always a representation of one physical
99 IOMMU, not necessarily of a virtualized IOMMU. For VMMs that want the full
100 virtualization features from physical IOMMUs, it is suggested to build the
101 same number of virtualized IOMMUs as the number of physical IOMMUs, so the
102 passed-through devices would be connected to their own virtualized IOMMUs
103 backed by corresponding vIOMMU objects, in which case a guest OS would do
104 the "dispatch" naturally instead of VMM trappings.
105
106 - IOMMUFD_OBJ_VDEVICE, representing a virtual device for an IOMMUFD_OBJ_DEVICE
107 against an IOMMUFD_OBJ_VIOMMU. This virtual device holds the device's virtual
108 information or attributes (related to the vIOMMU) in a VM. An immediate vDATA
109 example can be the virtual ID of the device on a vIOMMU, which is a unique ID
110 that VMM assigns to the device for a translation channel/port of the vIOMMU,
111 e.g. vSID of ARM SMMUv3, vDeviceID of AMD IOMMU, and vRID of Intel VT-d to a
112 Context Table. Potential use cases of some advanced security information can
113 be forwarded via this object too, such as security level or realm information
114 in a Confidential Compute Architecture. A VMM should create a vDEVICE object
115 to forward all the device information in a VM, when it connects a device to a
116 vIOMMU, which is a separate ioctl call from attaching the same device to an
117 HWPT_PAGING that the vIOMMU holds.
118
119 - IOMMUFD_OBJ_VEVENTQ, representing a software queue for a vIOMMU to report its
120 events such as translation faults occurred to a nested stage-1 (excluding I/O
121 page faults that should go through IOMMUFD_OBJ_FAULT) and HW-specific events.
122 This queue object provides user space an FD to poll/read the vIOMMU events. A
123 vIOMMU object must be created first to get its viommu_id, which could be then
124 used to allocate a vEVENTQ. Each vIOMMU can support multiple types of vEVENTS,
125 but is confined to one vEVENTQ per vEVENTQ type.
126
127 - IOMMUFD_OBJ_HW_QUEUE, representing a hardware accelerated queue, as a subset
128 of IOMMU's virtualization features, for the IOMMU HW to directly read or write
129 the virtual queue memory owned by a guest OS. This HW-acceleration feature can
130 allow VM to work with the IOMMU HW directly without a VM Exit, so as to reduce
131 overhead from the hypercalls. Along with the HW QUEUE object, iommufd provides
132 user space an mmap interface for VMM to mmap a physical MMIO region from the
133 host physical address space to the guest physical address space, allowing the
134 guest OS to directly control the allocated HW QUEUE. Thus, when allocating a
135 HW QUEUE, the VMM must request a pair of mmap info (offset/length) and pass in
136 exactly to an mmap syscall via its offset and length arguments.
137
138 All user-visible objects are destroyed via the IOMMU_DESTROY uAPI.
139
140 The diagrams below show relationships between user-visible objects and kernel
141 datastructures (external to iommufd), with numbers referred to operations
142 creating the objects and links::
143
144 _______________________________________________________________________
145 | iommufd (HWPT_PAGING only) |
146 | |
147 | [1] [3] [2] |
148 | ________________ _____________ ________ |
149 | | | | | | | |
150 | | IOAS |<---| HWPT_PAGING |<---------------------| DEVICE | |
151 | |________________| |_____________| |________| |
152 | | | | |
153 |_________|____________________|__________________________________|_____|
154 | | |
155 | ______v_____ ___v__
156 | PFN storage | (paging) | |struct|
157 |------------>|iommu_domain|<-----------------------|device|
158 |____________| |______|
159
160 _______________________________________________________________________
161 | iommufd (with HWPT_NESTED) |
162 | |
163 | [1] [3] [4] [2] |
164 | ________________ _____________ _____________ ________ |
165 | | | | | | | | | |
166 | | IOAS |<---| HWPT_PAGING |<---| HWPT_NESTED |<--| DEVICE | |
167 | |________________| |_____________| |_____________| |________| |
168 | | | | | |
169 |_________|____________________|__________________|_______________|_____|
170 | | | |
171 | ______v_____ ______v_____ ___v__
172 | PFN storage | (paging) | | (nested) | |struct|
173 |------------>|iommu_domain|<----|iommu_domain|<----|device|
174 |____________| |____________| |______|
175
176 _______________________________________________________________________
177 | iommufd (with vIOMMU/vDEVICE) |
178 | |
179 | [5] [6] |
180 | _____________ _____________ |
181 | | | | | |
182 | |----------------| vIOMMU |<---| vDEVICE |<----| |
183 | | | | |_____________| | |
184 | | | | | |
185 | | [1] | | [4] | [2] |
186 | | ______ | | _____________ _|______ |
187 | | | | | [3] | | | | | |
188 | | | IOAS |<---|(HWPT_PAGING)|<---| HWPT_NESTED |<--| DEVICE | |
189 | | |______| |_____________| |_____________| |________| |
190 | | | | | | |
191 |______|________|______________|__________________|_______________|_____|
192 | | | | |
193 ______v_____ | ______v_____ ______v_____ ___v__
194 | struct | | PFN | (paging) | | (nested) | |struct|
195 |iommu_device| |------>|iommu_domain|<----|iommu_domain|<----|device|
196 |____________| storage|____________| |____________| |______|
197
198 1. IOMMUFD_OBJ_IOAS is created via the IOMMU_IOAS_ALLOC uAPI. An iommufd can
199 hold multiple IOAS objects. IOAS is the most generic object and does not
200 expose interfaces that are specific to single IOMMU drivers. All operations
201 on the IOAS must operate equally on each of the iommu_domains inside of it.
202
203 2. IOMMUFD_OBJ_DEVICE is created when an external driver calls the IOMMUFD kAPI
204 to bind a device to an iommufd. The driver is expected to implement a set of
205 ioctls to allow userspace to initiate the binding operation. Successful
206 completion of this operation establishes the desired DMA ownership over the
207 device. The driver must also set the driver_managed_dma flag and must not
208 touch the device until this operation succeeds.
209
210 3. IOMMUFD_OBJ_HWPT_PAGING can be created in two ways:
211
212 * IOMMUFD_OBJ_HWPT_PAGING is automatically created when an external driver
213 calls the IOMMUFD kAPI to attach a bound device to an IOAS. Similarly the
214 external driver uAPI allows userspace to initiate the attaching operation.
215 If a compatible member HWPT_PAGING object exists in the IOAS's HWPT_PAGING
216 list, then it will be reused. Otherwise a new HWPT_PAGING that represents
217 an iommu_domain to userspace will be created, and then added to the list.
218 Successful completion of this operation sets up the linkages among IOAS,
219 device and iommu_domain. Once this completes the device could do DMA.
220
221 * IOMMUFD_OBJ_HWPT_PAGING can be manually created via the IOMMU_HWPT_ALLOC
222 uAPI, provided an ioas_id via @pt_id to associate the new HWPT_PAGING to
223 the corresponding IOAS object. The benefit of this manual allocation is to
224 allow allocation flags (defined in enum iommufd_hwpt_alloc_flags), e.g. it
225 allocates a nesting parent HWPT_PAGING if the IOMMU_HWPT_ALLOC_NEST_PARENT
226 flag is set.
227
228 4. IOMMUFD_OBJ_HWPT_NESTED can be only manually created via the IOMMU_HWPT_ALLOC
229 uAPI, provided an hwpt_id or a viommu_id of a vIOMMU object encapsulating a
230 nesting parent HWPT_PAGING via @pt_id to associate the new HWPT_NESTED object
231 to the corresponding HWPT_PAGING object. The associating HWPT_PAGING object
232 must be a nesting parent manually allocated via the same uAPI previously with
233 an IOMMU_HWPT_ALLOC_NEST_PARENT flag, otherwise the allocation will fail. The
234 allocation will be further validated by the IOMMU driver to ensure that the
235 nesting parent domain and the nested domain being allocated are compatible.
236 Successful completion of this operation sets up linkages among IOAS, device,
237 and iommu_domains. Once this completes the device could do DMA via a 2-stage
238 translation, a.k.a nested translation. Note that multiple HWPT_NESTED objects
239 can be allocated by (and then associated to) the same nesting parent.
240
241 .. note::
242
243 Either a manual IOMMUFD_OBJ_HWPT_PAGING or an IOMMUFD_OBJ_HWPT_NESTED is
244 created via the same IOMMU_HWPT_ALLOC uAPI. The difference is at the type
245 of the object passed in via the @pt_id field of struct iommufd_hwpt_alloc.
246
247 5. IOMMUFD_OBJ_VIOMMU can be only manually created via the IOMMU_VIOMMU_ALLOC
248 uAPI, provided a dev_id (for the device's physical IOMMU to back the vIOMMU)
249 and an hwpt_id (to associate the vIOMMU to a nesting parent HWPT_PAGING). The
250 iommufd core will link the vIOMMU object to the struct iommu_device that the
251 struct device is behind. And an IOMMU driver can implement a viommu_alloc op
252 to allocate its own vIOMMU data structure embedding the core-level structure
253 iommufd_viommu and some driver-specific data. If necessary, the driver can
254 also configure its HW virtualization feature for that vIOMMU (and thus for
255 the VM). Successful completion of this operation sets up the linkages between
256 the vIOMMU object and the HWPT_PAGING, then this vIOMMU object can be used
257 as a nesting parent object to allocate an HWPT_NESTED object described above.
258
259 6. IOMMUFD_OBJ_VDEVICE can be only manually created via the IOMMU_VDEVICE_ALLOC
260 uAPI, provided a viommu_id for an iommufd_viommu object and a dev_id for an
261 iommufd_device object. The vDEVICE object will be the binding between these
262 two parent objects. Another @virt_id will be also set via the uAPI providing
263 the iommufd core an index to store the vDEVICE object to a vDEVICE array per
264 vIOMMU. If necessary, the IOMMU driver may choose to implement a vdevce_alloc
265 op to init its HW for virtualization feature related to a vDEVICE. Successful
266 completion of this operation sets up the linkages between vIOMMU and device.
267
268 A device can only bind to an iommufd due to DMA ownership claim and attach to at
269 most one IOAS object (no support of PASID yet).
270
271 Kernel Datastructure
272 --------------------
273
274 User visible objects are backed by following datastructures:
275
276 - iommufd_ioas for IOMMUFD_OBJ_IOAS.
277 - iommufd_device for IOMMUFD_OBJ_DEVICE.
278 - iommufd_hwpt_paging for IOMMUFD_OBJ_HWPT_PAGING.
279 - iommufd_hwpt_nested for IOMMUFD_OBJ_HWPT_NESTED.
280 - iommufd_fault for IOMMUFD_OBJ_FAULT.
281 - iommufd_viommu for IOMMUFD_OBJ_VIOMMU.
282 - iommufd_vdevice for IOMMUFD_OBJ_VDEVICE.
283 - iommufd_veventq for IOMMUFD_OBJ_VEVENTQ.
284 - iommufd_hw_queue for IOMMUFD_OBJ_HW_QUEUE.
285
286 Several terminologies when looking at these datastructures:
287
288 - Automatic domain - refers to an iommu domain created automatically when
289 attaching a device to an IOAS object. This is compatible to the semantics of
290 VFIO type1.
291
292 - Manual domain - refers to an iommu domain designated by the user as the
293 target pagetable to be attached to by a device. Though currently there are
294 no uAPIs to directly create such domain, the datastructure and algorithms
295 are ready for handling that use case.
296
297 - In-kernel user - refers to something like a VFIO mdev that is using the
298 IOMMUFD access interface to access the IOAS. This starts by creating an
299 iommufd_access object that is similar to the domain binding a physical device
300 would do. The access object will then allow converting IOVA ranges into struct
301 page * lists, or doing direct read/write to an IOVA.
302
303 iommufd_ioas serves as the metadata datastructure to manage how IOVA ranges are
304 mapped to memory pages, composed of:
305
306 - struct io_pagetable holding the IOVA map
307 - struct iopt_area's representing populated portions of IOVA
308 - struct iopt_pages representing the storage of PFNs
309 - struct iommu_domain representing the IO page table in the IOMMU
310 - struct iopt_pages_access representing in-kernel users of PFNs
311 - struct xarray pinned_pfns holding a list of pages pinned by in-kernel users
312
313 Each iopt_pages represents a logical linear array of full PFNs. The PFNs are
314 ultimately derived from userspace VAs via an mm_struct. Once they have been
315 pinned the PFNs are stored in IOPTEs of an iommu_domain or inside the pinned_pfns
316 xarray if they have been pinned through an iommufd_access.
317
318 PFN have to be copied between all combinations of storage locations, depending
319 on what domains are present and what kinds of in-kernel "software access" users
320 exist. The mechanism ensures that a page is pinned only once.
321
322 An io_pagetable is composed of iopt_areas pointing at iopt_pages, along with a
323 list of iommu_domains that mirror the IOVA to PFN map.
324
325 Multiple io_pagetable-s, through their iopt_area-s, can share a single
326 iopt_pages which avoids multi-pinning and double accounting of page
327 consumption.
328
329 iommufd_ioas is shareable between subsystems, e.g. VFIO and VDPA, as long as
330 devices managed by different subsystems are bound to a same iommufd.
331
332 IOMMUFD User API
333 ================
334
335 .. kernel-doc:: include/uapi/linux/iommufd.h
336
337 IOMMUFD Kernel API
338 ==================
339
340 The IOMMUFD kAPI is device-centric with group-related tricks managed behind the
341 scene. This allows the external drivers calling such kAPI to implement a simple
342 device-centric uAPI for connecting its device to an iommufd, instead of
343 explicitly imposing the group semantics in its uAPI as VFIO does.
344
345 .. kernel-doc:: drivers/iommu/iommufd/device.c
346 :export:
347
348 .. kernel-doc:: drivers/iommu/iommufd/main.c
349 :export:
350
351 VFIO and IOMMUFD
352 ----------------
353
354 Connecting a VFIO device to iommufd can be done in two ways.
355
356 First is a VFIO compatible way by directly implementing the /dev/vfio/vfio
357 container IOCTLs by mapping them into io_pagetable operations. Doing so allows
358 the use of iommufd in legacy VFIO applications by symlinking /dev/vfio/vfio to
359 /dev/iommufd or extending VFIO to SET_CONTAINER using an iommufd instead of a
360 container fd.
361
362 The second approach directly extends VFIO to support a new set of device-centric
363 user API based on aforementioned IOMMUFD kernel API. It requires userspace
364 change but better matches the IOMMUFD API semantics and easier to support new
365 iommufd features when comparing it to the first approach.
366
367 Currently both approaches are still work-in-progress.
368
369 There are still a few gaps to be resolved to catch up with VFIO type1, as
370 documented in iommufd_vfio_check_extension().
371
372 Future TODOs
373 ============
374
375 Currently IOMMUFD supports only kernel-managed I/O page table, similar to VFIO
376 type1. New features on the radar include:
377
378 - Binding iommu_domain's to PASID/SSID
379 - Userspace page tables, for ARM, x86 and S390
380 - Kernel bypass'd invalidation of user page tables
381 - Re-use of the KVM page table in the IOMMU
382 - Dirty page tracking in the IOMMU
383 - Runtime Increase/Decrease of IOPTE size
384 - PRI support with faults resolved in userspace
385

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

개요

1-26

IOMMUFD는 파일 디스크립터를 통해 사용자 공간에서 I/O 페이지 테이블을 관리하는 관점으로 IOMMU 서브시스템을 제어하는 사용자 API입니다. DMA를 사용자 공간에 공개하려는 모든 드라이버가 공통으로 사용할 수 있도록 설계되었습니다.

이 API를 채택하는 드라이버는 기존 또는 과거에 자체 구현했던 IOMMU 로직, 예를 들어 `vfio_iommu_type1.c`를 장기적으로 폐기할 것으로 예상됩니다.

최소 기능으로 모든 IOMMU의 I/O 주소 공간과 I/O 페이지 테이블 관리를 보편적으로 지원하며, 특정 하드웨어 기능을 위한 비범용 기능도 확장할 수 있는 구조입니다.

대문자 `IOMMUFD`는 서브시스템을 뜻하고, 소문자 `iommufd`는 사용자 공간이 `/dev/iommu`를 통해 만든 파일 디스크립터를 뜻합니다. 문서 작성자는 Jason Gunthorpe와 Kevin Tian이며 라이선스는 GPL-2.0+입니다.

IOMMUFD 용어
항목설명
IOMMUFDIOMMU 사용자 API 서브시스템
iommufd/dev/iommu에서 생성한 사용자 공간 파일 디스크립터
주요 대상사용자 공간에 DMA를 공개하는 드라이버
대체 대상 예vfio_iommu_type1.c의 내부 IOMMU 로직

서브시스템과 사용자 파일 디스크립터 표기를 구분합니다.

.. SPDX-License-Identifier: GPL-2.0+

=======
IOMMUFD
=======

:Author: Jason Gunthorpe
:Author: Kevin Tian

Overview
========

IOMMUFD is the user API to control the IOMMU subsystem as it relates to managing
IO page tables from userspace using file descriptors. It intends to be general
and consumable by any driver that wants to expose DMA to userspace. These
drivers are eventually expected to deprecate any internal IOMMU logic
they may already/historically implement (e.g. vfio_iommu_type1.c).

At minimum iommufd provides universal support of managing I/O address spaces and
I/O page tables for all IOMMUs, with room in the design to add non-generic
features to cater to specific hardware functionality.

In this context the capital letter (IOMMUFD) refers to the subsystem while the
small letter (iommufd) refers to the file descriptors created via /dev/iommu for
use by userspace.

IOAS, DEVICE와 하드웨어 페이지 테이블 객체

27-65

`IOMMUFD_OBJ_IOAS`는 I/O 주소 공간(IOAS)을 나타내며 사용자 메모리를 IOVA 범위에 map/unmap할 수 있습니다. VFIO container의 기능적 대체물이고, VFIO container처럼 IOVA 매핑을 내부의 `iommu_domain` 목록에 복제합니다.

`IOMMUFD_OBJ_DEVICE`는 외부 드라이버가 iommufd에 bind한 장치를 나타냅니다.

`IOMMUFD_OBJ_HWPT_PAGING`은 IOMMU 드라이버가 관리하는 실제 하드웨어 I/O 페이지 테이블 하나, 즉 `struct iommu_domain` 하나를 나타냅니다. `PAGING`은 이 HWPT가 IOAS에 연결되어야 하고 `__IOMMU_DOMAIN_PAGING` 기능 플래그를 가진 `iommu_domain`이 기반임을 뜻합니다.

HWPT_PAGING은 사용자 공간에서 동작하는 장치를 위한 UNMANAGED stage-1 domain일 수도 있고, guest 물리 주소를 host 물리 주소로 변환하는 nesting parent stage-2 domain일 수도 있습니다. IOAS는 동일 IOVA 매핑을 공유하는 HWPT_PAGING 목록을 가지며 모든 구성원과 매핑을 동기화합니다.

`IOMMUFD_OBJ_HWPT_NESTED`는 사용자 공간, 예를 들어 guest OS가 관리하는 실제 하드웨어 I/O 페이지 테이블입니다. `IOMMU_DOMAIN_NESTED` 유형의 `iommu_domain`이 기반이며 HWPT_PAGING에 연결해야 합니다.

HWPT_NESTED는 사용자 공간 장치의 stage-1 domain이어야 하고, 생성할 때 연결할 nesting parent stage-2 domain을 지정해야 합니다. 이 사용자 관리 nested stage-1 페이지 테이블은 보통 guest IOVA를 guest 물리 주소로 매핑합니다.

핵심 사용자 객체
항목설명
IOMMUFD_OBJ_IOASIOVA map/unmap과 iommu_domain 목록 동기화
IOMMUFD_OBJ_DEVICE외부 드라이버가 bind한 장치
IOMMUFD_OBJ_HWPT_PAGINGIOMMU 드라이버 관리 paging iommu_domain
HWPT_PAGING stage-1사용자 공간 장치의 UNMANAGED domain
HWPT_PAGING stage-2guest PA에서 host PA로 가는 nesting parent
IOMMUFD_OBJ_HWPT_NESTEDguest OS 등 사용자 공간이 관리하는 nested stage-1 domain
HWPT_NESTED 매핑guest IOVA에서 guest PA

객체가 소유하는 주소 공간과 관리 주체를 구분합니다.

Key Concepts
============

User Visible Objects
--------------------

Following IOMMUFD objects are exposed to userspace:

- IOMMUFD_OBJ_IOAS, representing an I/O address space (IOAS), allowing map/unmap
  of user space memory into ranges of I/O Virtual Address (IOVA).

  The IOAS is a functional replacement for the VFIO container, and like the VFIO
  container it copies an IOVA map to a list of iommu_domains held within it.

- IOMMUFD_OBJ_DEVICE, representing a device that is bound to iommufd by an
  external driver.

- IOMMUFD_OBJ_HWPT_PAGING, representing an actual hardware I/O page table
  (i.e. a single struct iommu_domain) managed by the iommu driver. "PAGING"
  primarily indicates this type of HWPT should be linked to an IOAS. It also
  indicates that it is backed by an iommu_domain with __IOMMU_DOMAIN_PAGING
  feature flag. This can be either an UNMANAGED stage-1 domain for a device
  running in the user space, or a nesting parent stage-2 domain for mappings
  from guest-level physical addresses to host-level physical addresses.

  The IOAS has a list of HWPT_PAGINGs that share the same IOVA mapping and
  it will synchronize its mapping with each member HWPT_PAGING.

- IOMMUFD_OBJ_HWPT_NESTED, representing an actual hardware I/O page table
  (i.e. a single struct iommu_domain) managed by user space (e.g. guest OS).
  "NESTED" indicates that this type of HWPT should be linked to an HWPT_PAGING.
  It also indicates that it is backed by an iommu_domain that has a type of
  IOMMU_DOMAIN_NESTED. This must be a stage-1 domain for a device running in
  the user space (e.g. in a guest VM enabling the IOMMU nested translation
  feature.) As such, it must be created with a given nesting parent stage-2
  domain to associate to. This nested stage-1 page table managed by the user
  space usually has mappings from guest-level I/O virtual addresses to guest-
  level physical addresses.

FAULT와 vIOMMU 객체

66-105

`IOMMUFD_FAULT`는 IOMMU 하드웨어의 PRI(Page Request Interface)를 사용해 HWPT가 보고한 I/O 페이지 폴트를 담는 소프트웨어 큐입니다. 사용자 공간은 이 객체의 FD를 poll하여 폴트 이벤트를 받고 응답할 수 있습니다.

폴트 지원 HWPT를 만들려면 먼저 FAULT 객체를 생성해 `fault_id`를 얻고, `IOMMU_HWPT_ALLOC`의 flags에 `IOMMU_HWPT_FAULT_ID_VALID`를 설정하여 그 ID를 전달해야 합니다.

`IOMMUFD_OBJ_VIOMMU`는 VM에 전달하거나 공유하는 물리 IOMMU 인스턴스의 한 slice입니다. 하드웨어 가속 가상화 기능과 VM이 사용하는 소프트웨어 자원을 포함할 수 있습니다.

vIOMMU가 제공할 수 있는 기능
항목설명
보안 namespaceguest 소유 ID와 guest 제어 cache tag
비장치 이벤트invalidation queue 오류 같은 보고
공유 nesting parent여러 물리 IOMMU에 걸친 공유 page table 접근
플랫폼 ID 가상화RID 등
paravirtual invalidation반가상화 무효화 전달
직접 할당 queue직접 할당한 invalidation queue
직접 할당 interruptguest에 직접 할당한 인터럽트

플랫폼별 물리 IOMMU slice의 가상화 자원을 묶습니다.

vIOMMU는 보통 하드웨어 가속 가상화를 위해 nesting parent 페이지 테이블에 접근합니다. 따라서 nesting parent HWPT_PAGING을 지정해 만들고 그 객체를 캡슐화합니다. 이후 캡슐화된 HWPT_PAGING 대신 vIOMMU를 parent로 사용해 HWPT_NESTED를 할당할 수 있습니다.

이름이 vIOMMU라고 해서 VM 안의 가상 IOMMU 하나와 반드시 일대일인 것은 아닙니다. 여러 물리 IOMMU가 있는 시스템에서 VM은 하나의 거대한 가상 IOMMU를 가질 수 있고, VMM은 요청을 물리 IOMMU별 vIOMMU 객체로 분배할 수 있습니다.

즉 vIOMMU는 항상 물리 IOMMU 하나의 표현이지 가상 IOMMU 자체의 표현은 아닙니다. 물리 IOMMU의 전체 가상화 기능을 원하는 VMM은 물리 IOMMU 수와 같은 수의 가상 IOMMU를 만들어 pass-through 장치를 대응 vIOMMU가 뒷받침하는 가상 IOMMU에 연결하는 것이 권장됩니다. 그러면 VMM trap 대신 guest OS가 자연스럽게 분배합니다.

FAULT 지원 HWPT 생성
IOMMUFD_FAULT 생성fault_id 획득IOMMU_HWPT_FAULT_ID_VALID 설정IOMMU_HWPT_ALLOC 호출FD poll로 폴트 수신사용자 공간에서 이벤트 응답

FAULT 객체를 먼저 만들고 그 ID를 HWPT 할당에 사용합니다.

- IOMMUFD_FAULT, representing a software queue for an HWPT reporting IO page
  faults using the IOMMU HW's PRI (Page Request Interface). This queue object
  provides user space an FD to poll the page fault events and also to respond
  to those events. A FAULT object must be created first to get a fault_id that
  could be then used to allocate a fault-enabled HWPT via the IOMMU_HWPT_ALLOC
  command by setting the IOMMU_HWPT_FAULT_ID_VALID bit in its flags field.

- IOMMUFD_OBJ_VIOMMU, representing a slice of the physical IOMMU instance,
  passed to or shared with a VM. It may be some HW-accelerated virtualization
  features and some SW resources used by the VM. For examples:

  * Security namespace for guest owned ID, e.g. guest-controlled cache tags
  * Non-device-affiliated event reporting, e.g. invalidation queue errors
  * Access to a shareable nesting parent pagetable across physical IOMMUs
  * Virtualization of various platforms IDs, e.g. RIDs and others
  * Delivery of paravirtualized invalidation
  * Direct assigned invalidation queues
  * Direct assigned interrupts

  Such a vIOMMU object generally has the access to a nesting parent pagetable
  to support some HW-accelerated virtualization features. So, a vIOMMU object
  must be created given a nesting parent HWPT_PAGING object, and then it would
  encapsulate that HWPT_PAGING object. Therefore, a vIOMMU object can be used
  to allocate an HWPT_NESTED object in place of the encapsulated HWPT_PAGING.

  .. note::

     The name "vIOMMU" isn't necessarily identical to a virtualized IOMMU in a
     VM. A VM can have one giant virtualized IOMMU running on a machine having
     multiple physical IOMMUs, in which case the VMM will dispatch the requests
     or configurations from this single virtualized IOMMU instance to multiple
     vIOMMU objects created for individual slices of different physical IOMMUs.
     In other words, a vIOMMU object is always a representation of one physical
     IOMMU, not necessarily of a virtualized IOMMU. For VMMs that want the full
     virtualization features from physical IOMMUs, it is suggested to build the
     same number of virtualized IOMMUs as the number of physical IOMMUs, so the
     passed-through devices would be connected to their own virtualized IOMMUs
     backed by corresponding vIOMMU objects, in which case a guest OS would do
     the "dispatch" naturally instead of VMM trappings.

vDEVICE, vEVENTQ와 HW_QUEUE

106-143

`IOMMUFD_OBJ_VDEVICE`는 `IOMMUFD_OBJ_VIOMMU`에 대한 `IOMMUFD_OBJ_DEVICE`의 가상 장치입니다. VM 안에서 vIOMMU와 관련된 장치의 가상 정보와 속성을 보관합니다.

즉시 사용할 수 있는 vDATA의 예는 vIOMMU 변환 channel/port에 대해 VMM이 장치에 부여하는 고유 가상 ID입니다. ARM SMMUv3의 vSID, AMD IOMMU의 vDeviceID, Intel VT-d Context Table의 vRID가 여기에 해당합니다. Confidential Compute Architecture의 보안 수준이나 realm 정보 같은 고급 보안 속성도 전달할 수 있습니다.

VMM이 장치를 vIOMMU에 연결할 때는 VM의 모든 장치 정보를 전달하기 위해 vDEVICE를 만들어야 합니다. 이는 같은 장치를 vIOMMU가 보유한 HWPT_PAGING에 attach하는 호출과는 별도의 ioctl입니다.

`IOMMUFD_OBJ_VEVENTQ`는 nested stage-1에서 발생한 translation fault와 하드웨어별 이벤트를 vIOMMU가 보고하는 소프트웨어 큐입니다. I/O page fault는 제외되며 그것은 `IOMMUFD_OBJ_FAULT`를 통해 전달해야 합니다.

사용자 공간은 vEVENTQ FD를 poll/read합니다. 먼저 vIOMMU를 만들어 `viommu_id`를 얻은 뒤 vEVENTQ를 할당합니다. vIOMMU 하나가 여러 vEVENT 유형을 지원할 수 있지만 각 vEVENTQ 유형마다 큐는 하나만 허용됩니다.

`IOMMUFD_OBJ_HW_QUEUE`는 guest OS가 소유한 가상 큐 메모리를 IOMMU 하드웨어가 직접 읽고 쓰는 하드웨어 가속 큐입니다. VM exit와 hypercall 오버헤드를 줄이기 위해 VM이 IOMMU 하드웨어와 직접 동작하게 합니다.

iommufd는 VMM이 host 물리 주소 공간의 MMIO 영역을 guest 물리 주소 공간에 mmap할 인터페이스를 함께 제공합니다. HW_QUEUE를 할당할 때 VMM은 mmap 정보의 offset/length 쌍을 요청하고, 정확히 그 값을 `mmap` 시스템 호출의 인자로 전달해야 합니다.

모든 사용자 가시 객체는 `IOMMU_DESTROY` uAPI로 파괴합니다.

가상화·큐 객체
항목설명
IOMMUFD_OBJ_VDEVICEvIOMMU에 연결된 장치의 가상 ID·보안 속성
IOMMUFD_OBJ_VEVENTQtranslation fault와 HW 이벤트용 poll/read FD
IOMMUFD_OBJ_FAULTPRI 기반 I/O page fault와 응답
IOMMUFD_OBJ_HW_QUEUEguest가 직접 제어하는 HW 가속 큐
HW_QUEUE mmap할당에서 받은 offset/length를 그대로 사용
객체 파괴IOMMU_DESTROY

이벤트 종류와 FD 사용 방식을 구분합니다.

- IOMMUFD_OBJ_VDEVICE, representing a virtual device for an IOMMUFD_OBJ_DEVICE
  against an IOMMUFD_OBJ_VIOMMU. This virtual device holds the device's virtual
  information or attributes (related to the vIOMMU) in a VM. An immediate vDATA
  example can be the virtual ID of the device on a vIOMMU, which is a unique ID
  that VMM assigns to the device for a translation channel/port of the vIOMMU,
  e.g. vSID of ARM SMMUv3, vDeviceID of AMD IOMMU, and vRID of Intel VT-d to a
  Context Table. Potential use cases of some advanced security information can
  be forwarded via this object too, such as security level or realm information
  in a Confidential Compute Architecture. A VMM should create a vDEVICE object
  to forward all the device information in a VM, when it connects a device to a
  vIOMMU, which is a separate ioctl call from attaching the same device to an
  HWPT_PAGING that the vIOMMU holds.

- IOMMUFD_OBJ_VEVENTQ, representing a software queue for a vIOMMU to report its
  events such as translation faults occurred to a nested stage-1 (excluding I/O
  page faults that should go through IOMMUFD_OBJ_FAULT) and HW-specific events.
  This queue object provides user space an FD to poll/read the vIOMMU events. A
  vIOMMU object must be created first to get its viommu_id, which could be then
  used to allocate a vEVENTQ. Each vIOMMU can support multiple types of vEVENTS,
  but is confined to one vEVENTQ per vEVENTQ type.

- IOMMUFD_OBJ_HW_QUEUE, representing a hardware accelerated queue, as a subset
  of IOMMU's virtualization features, for the IOMMU HW to directly read or write
  the virtual queue memory owned by a guest OS. This HW-acceleration feature can
  allow VM to work with the IOMMU HW directly without a VM Exit, so as to reduce
  overhead from the hypercalls. Along with the HW QUEUE object, iommufd provides
  user space an mmap interface for VMM to mmap a physical MMIO region from the
  host physical address space to the guest physical address space, allowing the
  guest OS to directly control the allocated HW QUEUE. Thus, when allocating a
  HW QUEUE, the VMM must request a pair of mmap info (offset/length) and pass in
  exactly to an mmap syscall via its offset and length arguments.

All user-visible objects are destroyed via the IOMMU_DESTROY uAPI.

The diagrams below show relationships between user-visible objects and kernel
datastructures (external to iommufd), with numbers referred to operations
creating the objects and links::

사용자 객체와 커널 구조체 관계

144-197

원문의 세 ASCII 그림은 객체 생성 순서 번호와 iommufd 외부 커널 구조체의 연결을 보여 줍니다. 아래 흐름도는 같은 관계를 구조화하여 표현합니다.

HWPT_PAGING만 사용하는 관계
[1] IOAS 생성[3] HWPT_PAGING 연결[2] DEVICE bind·attachIOAS PFN storage -> paging iommu_domainstruct device -> paging iommu_domainDEVICE가 DMA 수행

IOAS의 PFN 저장소가 paging iommu_domain을 채우고 DEVICE가 그 domain에 연결됩니다.

HWPT_NESTED를 포함한 관계
[1] IOAS[3] nesting parent HWPT_PAGING[4] HWPT_NESTED[2] DEVICEnested iommu_domain -> paging iommu_domainstruct device -> nested iommu_domain2-stage DMA translation

nested stage-1이 paging stage-2 parent에 연결되어 2단계 변환을 구성합니다.

vIOMMU와 vDEVICE를 포함한 관계
[3] HWPT_PAGING과 IOAS 연결[5] vIOMMU가 HWPT_PAGING 캡슐화vIOMMU -> struct iommu_device[6] vDEVICE가 vIOMMU와 DEVICE 연결[4] HWPT_NESTED를 vIOMMU parent로 생성DEVICE -> nested iommu_domainguest 가상화 경로 완성

vIOMMU는 물리 iommu_device slice와 parent HWPT_PAGING을 캡슐화합니다.

그림의 작업 번호
항목설명
[1]IOMMUFD_OBJ_IOAS 생성
[2]IOMMUFD_OBJ_DEVICE bind
[3]IOMMUFD_OBJ_HWPT_PAGING 생성·연결
[4]IOMMUFD_OBJ_HWPT_NESTED 수동 생성
[5]IOMMUFD_OBJ_VIOMMU 수동 생성
[6]IOMMUFD_OBJ_VDEVICE 수동 생성

뒤의 번호별 설명과 일치합니다.

  _______________________________________________________________________
 |                      iommufd (HWPT_PAGING only)                       |
 |                                                                       |
 |        [1]                  [3]                                [2]    |
 |  ________________      _____________                        ________  |
 | |                |    |             |                      |        | |
 | |      IOAS      |<---| HWPT_PAGING |<---------------------| DEVICE | |
 | |________________|    |_____________|                      |________| |
 |         |                    |                                  |     |
 |_________|____________________|__________________________________|_____|
           |                    |                                  |
           |              ______v_____                          ___v__
           | PFN storage |  (paging)  |                        |struct|
           |------------>|iommu_domain|<-----------------------|device|
                         |____________|                        |______|

  _______________________________________________________________________
 |                      iommufd (with HWPT_NESTED)                       |
 |                                                                       |
 |        [1]                  [3]                [4]             [2]    |
 |  ________________      _____________      _____________     ________  |
 | |                |    |             |    |             |   |        | |
 | |      IOAS      |<---| HWPT_PAGING |<---| HWPT_NESTED |<--| DEVICE | |
 | |________________|    |_____________|    |_____________|   |________| |
 |         |                    |                  |               |     |
 |_________|____________________|__________________|_______________|_____|
           |                    |                  |               |
           |              ______v_____       ______v_____       ___v__
           | PFN storage |  (paging)  |     |  (nested)  |     |struct|
           |------------>|iommu_domain|<----|iommu_domain|<----|device|
                         |____________|     |____________|     |______|

  _______________________________________________________________________
 |                      iommufd (with vIOMMU/vDEVICE)                    |
 |                                                                       |
 |                             [5]                [6]                    |
 |                        _____________      _____________               |
 |                       |             |    |             |              |
 |      |----------------|    vIOMMU   |<---|   vDEVICE   |<----|        |
 |      |                |             |    |_____________|     |        |
 |      |                |             |                        |        |
 |      |      [1]       |             |          [4]           | [2]    |
 |      |     ______     |             |     _____________     _|______  |
 |      |    |      |    |     [3]     |    |             |   |        | |
 |      |    | IOAS |<---|(HWPT_PAGING)|<---| HWPT_NESTED |<--| DEVICE | |
 |      |    |______|    |_____________|    |_____________|   |________| |
 |      |        |              |                  |               |     |
 |______|________|______________|__________________|_______________|_____|
        |        |              |                  |               |
  ______v_____   |        ______v_____       ______v_____       ___v__
 |   struct   |  |  PFN  |  (paging)  |     |  (nested)  |     |struct|
 |iommu_device|  |------>|iommu_domain|<----|iommu_domain|<----|device|
 |____________|   storage|____________|     |____________|     |______|

작업 1·2: IOAS 생성과 DEVICE bind

198-209

1. `IOMMUFD_OBJ_IOAS`는 `IOMMU_IOAS_ALLOC` uAPI로 생성합니다. iommufd 하나가 여러 IOAS를 보유할 수 있습니다. IOAS는 가장 범용적인 객체이며 개별 IOMMU 드라이버 전용 인터페이스를 공개하지 않습니다. IOAS의 모든 작업은 내부의 각 `iommu_domain`에 동일하게 적용되어야 합니다.

2. 외부 드라이버가 IOMMUFD kAPI를 호출하여 장치를 iommufd에 bind하면 `IOMMUFD_OBJ_DEVICE`가 생성됩니다. 드라이버는 사용자 공간이 bind를 시작할 수 있는 ioctl 집합을 구현해야 합니다.

bind가 성공하면 장치의 DMA 소유권을 확보합니다. 드라이버는 `driver_managed_dma` 플래그를 설정해야 하고 bind 작업이 성공하기 전에는 장치를 건드려서는 안 됩니다.

IOAS와 DEVICE 생성
항목설명
IOMMU_IOAS_ALLOCIOAS 생성, iommufd당 여러 개 가능
외부 driver IOMMUFD kAPIDEVICE 생성
driver uAPI사용자 공간이 bind 시작
bind 성공DMA ownership 확보
driver 의무driver_managed_dma 설정, 성공 전 장치 접근 금지

객체 생성 주체와 성공 후 효과입니다.

1. IOMMUFD_OBJ_IOAS is created via the IOMMU_IOAS_ALLOC uAPI. An iommufd can
   hold multiple IOAS objects. IOAS is the most generic object and does not
   expose interfaces that are specific to single IOMMU drivers. All operations
   on the IOAS must operate equally on each of the iommu_domains inside of it.

2. IOMMUFD_OBJ_DEVICE is created when an external driver calls the IOMMUFD kAPI
   to bind a device to an iommufd. The driver is expected to implement a set of
   ioctls to allow userspace to initiate the binding operation. Successful
   completion of this operation establishes the desired DMA ownership over the
   device. The driver must also set the driver_managed_dma flag and must not
   touch the device until this operation succeeds.

작업 3: HWPT_PAGING 자동·수동 생성

210-227

3. `IOMMUFD_OBJ_HWPT_PAGING`은 자동 또는 수동으로 만들 수 있습니다.

자동 경로에서는 외부 드라이버가 bind된 장치를 IOAS에 attach하는 IOMMUFD kAPI를 호출합니다. 사용자 공간은 외부 드라이버 uAPI를 통해 이 작업을 시작합니다. IOAS의 HWPT_PAGING 목록에 호환되는 객체가 있으면 재사용하고, 없으면 `iommu_domain`을 나타내는 새 HWPT_PAGING을 만들어 목록에 추가합니다.

자동 attach가 성공하면 IOAS, device, `iommu_domain` 사이 연결이 완성되고 장치가 DMA를 수행할 수 있습니다.

수동 경로는 `IOMMU_HWPT_ALLOC` uAPI에 `@pt_id`로 `ioas_id`를 제공하여 새 HWPT_PAGING을 해당 IOAS와 연결합니다. 수동 할당은 `enum iommufd_hwpt_alloc_flags`의 플래그를 지정할 수 있다는 장점이 있습니다. 예를 들어 `IOMMU_HWPT_ALLOC_NEST_PARENT`를 설정하면 nesting parent HWPT_PAGING을 할당합니다.

HWPT_PAGING 생성
자동: DEVICE를 IOAS에 attach호환 HWPT_PAGING 검색있으면 재사용, 없으면 iommu_domain 생성수동: IOMMU_HWPT_ALLOC@pt_id에 ioas_id 제공NEST_PARENT 등 allocation flag 적용

호환 객체 재사용이 가능한 자동 경로와 플래그를 지정하는 수동 경로입니다.

3. IOMMUFD_OBJ_HWPT_PAGING can be created in two ways:

   * IOMMUFD_OBJ_HWPT_PAGING is automatically created when an external driver
     calls the IOMMUFD kAPI to attach a bound device to an IOAS. Similarly the
     external driver uAPI allows userspace to initiate the attaching operation.
     If a compatible member HWPT_PAGING object exists in the IOAS's HWPT_PAGING
     list, then it will be reused. Otherwise a new HWPT_PAGING that represents
     an iommu_domain to userspace will be created, and then added to the list.
     Successful completion of this operation sets up the linkages among IOAS,
     device and iommu_domain. Once this completes the device could do DMA.

   * IOMMUFD_OBJ_HWPT_PAGING can be manually created via the IOMMU_HWPT_ALLOC
     uAPI, provided an ioas_id via @pt_id to associate the new HWPT_PAGING to
     the corresponding IOAS object. The benefit of this manual allocation is to
     allow allocation flags (defined in enum iommufd_hwpt_alloc_flags), e.g. it
     allocates a nesting parent HWPT_PAGING if the IOMMU_HWPT_ALLOC_NEST_PARENT
     flag is set.

작업 4: HWPT_NESTED 생성

228-246

4. `IOMMUFD_OBJ_HWPT_NESTED`는 `IOMMU_HWPT_ALLOC` uAPI로만 수동 생성합니다. `@pt_id`에는 nesting parent HWPT_PAGING의 `hwpt_id` 또는 그 parent를 캡슐화한 vIOMMU의 `viommu_id`를 전달합니다.

연결 대상 HWPT_PAGING은 앞서 같은 uAPI에서 `IOMMU_HWPT_ALLOC_NEST_PARENT` 플래그로 수동 할당한 nesting parent여야 하며, 그렇지 않으면 할당이 실패합니다. IOMMU 드라이버는 parent domain과 새 nested domain의 호환성도 추가 검증합니다.

성공하면 IOAS, device, 여러 `iommu_domain` 사이 연결이 설정되고 장치는 nested translation이라 부르는 2단계 변환으로 DMA를 수행할 수 있습니다. 하나의 nesting parent에 여러 HWPT_NESTED를 할당하고 연결할 수 있습니다.

수동 HWPT_PAGING과 HWPT_NESTED는 같은 `IOMMU_HWPT_ALLOC`을 사용합니다. 둘의 차이는 `struct iommufd_hwpt_alloc`의 `@pt_id`로 전달한 객체 유형입니다.

HWPT_NESTED 할당 검증
NEST_PARENT HWPT_PAGING 준비hwpt_id 또는 viommu_id 선택@pt_id로 IOMMU_HWPT_ALLOCparent 유형 검사IOMMU driver 호환성 검사2-stage DMA 연결 완성

parent 지정과 드라이버 호환성 검사가 모두 성공해야 합니다.

4. IOMMUFD_OBJ_HWPT_NESTED can be only manually created via the IOMMU_HWPT_ALLOC
   uAPI, provided an hwpt_id or a viommu_id of a vIOMMU object encapsulating a
   nesting parent HWPT_PAGING via @pt_id to associate the new HWPT_NESTED object
   to the corresponding HWPT_PAGING object. The associating HWPT_PAGING object
   must be a nesting parent manually allocated via the same uAPI previously with
   an IOMMU_HWPT_ALLOC_NEST_PARENT flag, otherwise the allocation will fail. The
   allocation will be further validated by the IOMMU driver to ensure that the
   nesting parent domain and the nested domain being allocated are compatible.
   Successful completion of this operation sets up linkages among IOAS, device,
   and iommu_domains. Once this completes the device could do DMA via a 2-stage
   translation, a.k.a nested translation. Note that multiple HWPT_NESTED objects
   can be allocated by (and then associated to) the same nesting parent.

   .. note::

      Either a manual IOMMUFD_OBJ_HWPT_PAGING or an IOMMUFD_OBJ_HWPT_NESTED is
      created via the same IOMMU_HWPT_ALLOC uAPI. The difference is at the type
      of the object passed in via the @pt_id field of struct iommufd_hwpt_alloc.

작업 5·6: vIOMMU와 vDEVICE 생성

247-270

5. `IOMMUFD_OBJ_VIOMMU`는 `IOMMU_VIOMMU_ALLOC` uAPI로만 수동 생성합니다. 물리 IOMMU를 정하기 위한 `dev_id`와 nesting parent HWPT_PAGING에 연결할 `hwpt_id`를 제공합니다.

iommufd core는 vIOMMU를 `struct device` 뒤의 `struct iommu_device`에 연결합니다. IOMMU 드라이버는 `viommu_alloc` op를 구현해 core 구조체 `iommufd_viommu`와 driver 전용 데이터를 포함하는 자체 구조체를 할당하고, 필요하면 VM을 위한 하드웨어 가상화 기능을 설정할 수 있습니다.

성공하면 vIOMMU와 HWPT_PAGING이 연결되며 이 vIOMMU를 parent로 사용해 HWPT_NESTED를 할당할 수 있습니다.

6. `IOMMUFD_OBJ_VDEVICE`는 `IOMMU_VDEVICE_ALLOC` uAPI로만 수동 생성합니다. `iommufd_viommu`의 `viommu_id`, `iommufd_device`의 `dev_id`를 제공하며 vDEVICE가 두 parent 객체의 binding이 됩니다.

uAPI의 `@virt_id`는 vIOMMU별 vDEVICE 배열에 객체를 저장할 index입니다. IOMMU 드라이버는 필요하면 원문 표기의 `vdevce_alloc` op를 구현해 vDEVICE 관련 가상화 하드웨어를 초기화할 수 있습니다. 성공하면 vIOMMU와 device 연결이 완성됩니다.

DMA ownership claim 때문에 장치는 iommufd 하나에만 bind할 수 있고, 최대 IOAS 하나에만 attach할 수 있습니다. PASID는 아직 지원하지 않습니다.

vIOMMU·vDEVICE 인자
항목설명
IOMMU_VIOMMU_ALLOCdev_id + nesting parent hwpt_id
viommu_allocdriver별 vIOMMU 구조체·HW 가상화 설정
IOMMU_VDEVICE_ALLOCviommu_id + dev_id + virt_id
virt_idvIOMMU별 vDEVICE 배열 index
vdevce_alloc원문 표기의 driver vDEVICE 초기화 op
장치 제한iommufd 하나, IOAS 최대 하나, PASID 미지원

수동 할당에 필요한 ID와 연결 결과입니다.

5. IOMMUFD_OBJ_VIOMMU can be only manually created via the IOMMU_VIOMMU_ALLOC
   uAPI, provided a dev_id (for the device's physical IOMMU to back the vIOMMU)
   and an hwpt_id (to associate the vIOMMU to a nesting parent HWPT_PAGING). The
   iommufd core will link the vIOMMU object to the struct iommu_device that the
   struct device is behind. And an IOMMU driver can implement a viommu_alloc op
   to allocate its own vIOMMU data structure embedding the core-level structure
   iommufd_viommu and some driver-specific data. If necessary, the driver can
   also configure its HW virtualization feature for that vIOMMU (and thus for
   the VM). Successful completion of this operation sets up the linkages between
   the vIOMMU object and the HWPT_PAGING, then this vIOMMU object can be used
   as a nesting parent object to allocate an HWPT_NESTED object described above.

6. IOMMUFD_OBJ_VDEVICE can be only manually created via the IOMMU_VDEVICE_ALLOC
   uAPI, provided a viommu_id for an iommufd_viommu object and a dev_id for an
   iommufd_device object. The vDEVICE object will be the binding between these
   two parent objects. Another @virt_id will be also set via the uAPI providing
   the iommufd core an index to store the vDEVICE object to a vDEVICE array per
   vIOMMU. If necessary, the IOMMU driver may choose to implement a vdevce_alloc
   op to init its HW for virtualization feature related to a vDEVICE. Successful
   completion of this operation sets up the linkages between vIOMMU and device.

A device can only bind to an iommufd due to DMA ownership claim and attach to at
most one IOAS object (no support of PASID yet).

커널 자료구조와 용어

271-302

사용자 가시 객체는 대응 커널 자료구조가 뒷받침합니다.

객체와 커널 자료구조
항목설명
IOMMUFD_OBJ_IOASiommufd_ioas
IOMMUFD_OBJ_DEVICEiommufd_device
IOMMUFD_OBJ_HWPT_PAGINGiommufd_hwpt_paging
IOMMUFD_OBJ_HWPT_NESTEDiommufd_hwpt_nested
IOMMUFD_OBJ_FAULTiommufd_fault
IOMMUFD_OBJ_VIOMMUiommufd_viommu
IOMMUFD_OBJ_VDEVICEiommufd_vdevice
IOMMUFD_OBJ_VEVENTQiommufd_veventq
IOMMUFD_OBJ_HW_QUEUEiommufd_hw_queue

객체별 core 자료구조 이름을 보존합니다.

Automatic domain은 장치를 IOAS에 attach할 때 자동으로 생성되는 iommu domain이며 VFIO type1 의미론과 호환됩니다.

Manual domain은 사용자가 장치가 attach할 대상 page table로 지정한 iommu domain입니다. 현재 이런 domain을 직접 만드는 uAPI는 없지만 자료구조와 알고리즘은 이 사용 사례를 처리할 준비가 되어 있습니다.

In-kernel user는 VFIO mdev처럼 IOMMUFD access interface로 IOAS에 접근하는 커널 내부 사용자를 뜻합니다. 물리 장치의 domain bind와 비슷한 `iommufd_access` 객체를 먼저 만듭니다.

access 객체는 IOVA 범위를 `struct page *` 목록으로 변환하거나 IOVA를 직접 read/write할 수 있게 합니다.

핵심 용어
항목설명
Automatic domainDEVICE를 IOAS에 attach할 때 자동 생성, VFIO type1 호환
Manual domain사용자가 대상 page table로 지정
In-kernel useriommufd_access로 IOAS에 접근
access 기능IOVA -> struct page * 변환 또는 직접 read/write

domain 생성 주체와 IOAS 접근 방식을 구분합니다.

Kernel Datastructure
--------------------

User visible objects are backed by following datastructures:

- iommufd_ioas for IOMMUFD_OBJ_IOAS.
- iommufd_device for IOMMUFD_OBJ_DEVICE.
- iommufd_hwpt_paging for IOMMUFD_OBJ_HWPT_PAGING.
- iommufd_hwpt_nested for IOMMUFD_OBJ_HWPT_NESTED.
- iommufd_fault for IOMMUFD_OBJ_FAULT.
- iommufd_viommu for IOMMUFD_OBJ_VIOMMU.
- iommufd_vdevice for IOMMUFD_OBJ_VDEVICE.
- iommufd_veventq for IOMMUFD_OBJ_VEVENTQ.
- iommufd_hw_queue for IOMMUFD_OBJ_HW_QUEUE.

Several terminologies when looking at these datastructures:

- Automatic domain - refers to an iommu domain created automatically when
  attaching a device to an IOAS object. This is compatible to the semantics of
  VFIO type1.

- Manual domain - refers to an iommu domain designated by the user as the
  target pagetable to be attached to by a device. Though currently there are
  no uAPIs to directly create such domain, the datastructure and algorithms
  are ready for handling that use case.

- In-kernel user - refers to something like a VFIO mdev that is using the
  IOMMUFD access interface to access the IOAS. This starts by creating an
  iommufd_access object that is similar to the domain binding a physical device
  would do. The access object will then allow converting IOVA ranges into struct
  page * lists, or doing direct read/write to an IOVA.

iommufd_ioas 내부와 PFN 저장

303-331

`iommufd_ioas`는 IOVA 범위를 메모리 페이지에 매핑하는 방식을 관리하는 metadata 자료구조입니다.

iommufd_ioas 구성
항목설명
struct io_pagetableIOVA map 보유
struct iopt_area채워진 IOVA 부분 표현
struct iopt_pagesPFN 저장소
struct iommu_domainIOMMU의 I/O page table
struct iopt_pages_accessPFN의 in-kernel user
struct xarray pinned_pfnsin-kernel user가 pin한 페이지 목록

IOVA map, PFN 저장소, domain과 커널 내부 접근자를 함께 관리합니다.

각 `iopt_pages`는 완전한 PFN의 논리적 선형 배열입니다. PFN은 최종적으로 `mm_struct`를 통해 사용자 VA에서 얻습니다. pin한 PFN은 `iommu_domain`의 IOPTE에 저장하거나, `iommufd_access`를 통해 pin한 경우 `pinned_pfns` xarray에 저장합니다.

존재하는 domain과 커널 내부 software access 사용자 종류에 따라 모든 저장 위치 조합 사이에서 PFN을 복사해야 합니다. 이 메커니즘은 페이지 하나가 한 번만 pin되도록 보장합니다.

`io_pagetable`은 `iopt_pages`를 가리키는 `iopt_area`와 IOVA-to-PFN map을 mirror하는 `iommu_domain` 목록으로 구성됩니다.

여러 `io_pagetable`은 각자의 `iopt_area`를 통해 하나의 `iopt_pages`를 공유할 수 있습니다. 이로써 다중 pin과 페이지 소비량 중복 계상을 피합니다.

서로 다른 서브시스템이 관리하는 장치가 같은 iommufd에 bind되어 있다면 `iommufd_ioas`를 VFIO와 VDPA 같은 서브시스템 사이에서 공유할 수 있습니다.

PFN 저장과 공유
사용자 VA + mm_structiopt_pages 논리 PFN 배열페이지 1회 piniommu_domain IOPTE 또는 pinned_pfns xarrayiopt_area가 iopt_pages 참조여러 io_pagetable·서브시스템이 공유

사용자 VA에서 얻은 PFN을 한 번만 pin해 필요한 저장 위치에서 공유합니다.

iommufd_ioas serves as the metadata datastructure to manage how IOVA ranges are
mapped to memory pages, composed of:

- struct io_pagetable holding the IOVA map
- struct iopt_area's representing populated portions of IOVA
- struct iopt_pages representing the storage of PFNs
- struct iommu_domain representing the IO page table in the IOMMU
- struct iopt_pages_access representing in-kernel users of PFNs
- struct xarray pinned_pfns holding a list of pages pinned by in-kernel users

Each iopt_pages represents a logical linear array of full PFNs. The PFNs are
ultimately derived from userspace VAs via an mm_struct. Once they have been
pinned the PFNs are stored in IOPTEs of an iommu_domain or inside the pinned_pfns
xarray if they have been pinned through an iommufd_access.

PFN have to be copied between all combinations of storage locations, depending
on what domains are present and what kinds of in-kernel "software access" users
exist. The mechanism ensures that a page is pinned only once.

An io_pagetable is composed of iopt_areas pointing at iopt_pages, along with a
list of iommu_domains that mirror the IOVA to PFN map.

Multiple io_pagetable-s, through their iopt_area-s, can share a single
iopt_pages which avoids multi-pinning and double accounting of page
consumption.

iommufd_ioas is shareable between subsystems, e.g. VFIO and VDPA, as long as
devices managed by different subsystems are bound to a same iommufd.

IOMMUFD 사용자·커널 API

332-350

IOMMUFD 사용자 API의 kernel-doc 원본은 `include/uapi/linux/iommufd.h`입니다.

IOMMUFD kAPI는 device 중심이며 group 관련 처리는 내부에서 숨깁니다. 따라서 외부 드라이버는 VFIO처럼 uAPI에 group 의미론을 명시적으로 강제하지 않고, 장치를 iommufd에 연결하는 단순한 device 중심 uAPI를 구현할 수 있습니다.

커널 API 문서는 `drivers/iommu/iommufd/device.c`와 `drivers/iommu/iommufd/main.c`의 exported kernel-doc에서 생성됩니다.

API 문서 소스
항목설명
User APIinclude/uapi/linux/iommufd.h
Kernel device APIdrivers/iommu/iommufd/device.c :export:
Kernel core APIdrivers/iommu/iommufd/main.c :export:

Sphinx kernel-doc 지시문이 참조하는 경로입니다.

IOMMUFD User API
================

.. kernel-doc:: include/uapi/linux/iommufd.h

IOMMUFD Kernel API
==================

The IOMMUFD kAPI is device-centric with group-related tricks managed behind the
scene. This allows the external drivers calling such kAPI to implement a simple
device-centric uAPI for connecting its device to an iommufd, instead of
explicitly imposing the group semantics in its uAPI as VFIO does.

.. kernel-doc:: drivers/iommu/iommufd/device.c
   :export:

.. kernel-doc:: drivers/iommu/iommufd/main.c
   :export:

VFIO와 IOMMUFD

351-371

VFIO 장치를 iommufd에 연결하는 방법은 두 가지입니다.

첫 번째는 `/dev/vfio/vfio` container ioctl을 `io_pagetable` 작업에 매핑해 직접 구현하는 VFIO 호환 방식입니다. `/dev/vfio/vfio`를 `/dev/iommufd`에 symlink하거나, VFIO의 `SET_CONTAINER`가 container fd 대신 iommufd를 받게 확장하면 기존 VFIO 애플리케이션에서도 iommufd를 사용할 수 있습니다.

두 번째는 앞서 설명한 IOMMUFD kernel API를 기반으로 새로운 device 중심 사용자 API를 VFIO에 직접 추가하는 방법입니다. 사용자 공간 변경이 필요하지만 IOMMUFD 의미론에 더 잘 맞고 첫 번째 방식보다 새로운 iommufd 기능을 지원하기 쉽습니다.

현재 두 방식 모두 개발 중입니다. VFIO type1을 따라잡기 위해 해결해야 할 차이는 `iommufd_vfio_check_extension()`에 문서화되어 있습니다.

VFIO 연결 방식
항목설명
VFIO container 호환기존 ioctl을 io_pagetable 작업으로 매핑
호환 사용/dev/vfio/vfio symlink 또는 SET_CONTAINER 확장
device 중심 uAPIIOMMUFD kAPI 기반 새 VFIO API
장점IOMMUFD 의미론과 새 기능에 더 적합
현재 상태두 방식 모두 개발 중
남은 차이iommufd_vfio_check_extension()

호환성과 장기 확장성의 차이입니다.

VFIO and IOMMUFD
----------------

Connecting a VFIO device to iommufd can be done in two ways.

First is a VFIO compatible way by directly implementing the /dev/vfio/vfio
container IOCTLs by mapping them into io_pagetable operations. Doing so allows
the use of iommufd in legacy VFIO applications by symlinking /dev/vfio/vfio to
/dev/iommufd or extending VFIO to SET_CONTAINER using an iommufd instead of a
container fd.

The second approach directly extends VFIO to support a new set of device-centric
user API based on aforementioned IOMMUFD kernel API. It requires userspace
change but better matches the IOMMUFD API semantics and easier to support new
iommufd features when comparing it to the first approach.

Currently both approaches are still work-in-progress.

There are still a few gaps to be resolved to catch up with VFIO type1, as
documented in iommufd_vfio_check_extension().

향후 작업

372-384

현재 IOMMUFD는 VFIO type1과 비슷하게 kernel 관리 I/O 페이지 테이블만 지원합니다. 향후 검토 중인 기능은 다음과 같습니다.

IOMMUFD 향후 기능
항목설명
PASID/SSIDiommu_domain을 PASID/SSID에 bind
사용자 페이지 테이블ARM, x86, S390 지원
kernel bypass invalidation사용자 페이지 테이블을 kernel 우회하여 무효화
KVM page tableIOMMU에서 KVM 페이지 테이블 재사용
Dirty trackingIOMMU에서 dirty page 추적
IOPTE size런타임 크기 증가·감소
PRI사용자 공간에서 fault 해결

PASID·사용자 페이지 테이블·무효화·dirty tracking과 PRI가 주요 확장 축입니다.

Future TODOs
============

Currently IOMMUFD supports only kernel-managed I/O page table, similar to VFIO
type1. New features on the radar include:

 - Binding iommu_domain's to PASID/SSID
 - Userspace page tables, for ARM, x86 and S390
 - Kernel bypass'd invalidation of user page tables
 - Re-use of the KVM page table in the IOMMU
 - Dirty page tracking in the IOMMU
 - Runtime Increase/Decrease of IOPTE size
 - PRI support with faults resolved in userspace