History

Merge tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd

Pull iommufd implementation from Jason Gunthorpe: "iommufd is the user API to control the IOMMU subsystem as it relates to managing IO page tables that point at user space memory. It takes over from drivers/vfio/vfio_iommu_type1.c (aka the VFIO container) which is the VFIO specific interface for a similar idea. We see a broad need for extended features, some being highly IOMMU device specific: - Binding iommu_domain's to PASID/SSID - Userspace IO page tables, for ARM, x86 and S390 - Kernel bypassed 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 Many of these HW features exist to support VM use cases - for instance the combination of PASID, PRI and Userspace IO Page Tables allows an implementation of DMA Shared Virtual Addressing (vSVA) within a guest. Dirty tracking enables VM live migration with SRIOV devices and PASID support allow creating "scalable IOV" devices, among other things. As these features are fundamental to a VM platform they need to be uniformly exposed to all the driver families that do DMA into VMs, which is currently VFIO and VDPA" For more background, see the extended explanations in Jason's pull request: https://lore.kernel.org/lkml/Y5dzTU8dlmXTbzoJ@nvidia.com/ * tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd: (62 commits) iommufd: Change the order of MSI setup iommufd: Improve a few unclear bits of code iommufd: Fix comment typos vfio: Move vfio group specific code into group.c vfio: Refactor dma APIs for emulated devices vfio: Wrap vfio group module init/clean code into helpers vfio: Refactor vfio_device open and close vfio: Make vfio_device_open() truly device specific vfio: Swap order of vfio_device_container_register() and open_device() vfio: Set device->group in helper function vfio: Create wrappers for group register/unregister vfio: Move the sanity check of the group to vfio_create_group() vfio: Simplify vfio_create_group() iommufd: Allow iommufd to supply /dev/vfio/vfio vfio: Make vfio_container optionally compiled vfio: Move container related MODULE_ALIAS statements into container.c vfio-iommufd: Support iommufd for emulated VFIO devices vfio-iommufd: Support iommufd for physical VFIO devices vfio-iommufd: Allow iommufd to be used in place of a container fd vfio: Use IOMMU_CAP_ENFORCE_CACHE_COHERENCY for vfio_file_enforced_coherent() ...

Linus Torvalds committed 3 years ago

Commit 08cdc212 parents aa5ad10 d6c55c083 files · +12804 −1466Browse files

Showing the changes to include/uapi (1 of 83 files). Show all

Unified · Split

include/uapi/linux/iommufd.h+347−0
@@ -0,0 +1,347 @@
1+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2+/* Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES.
3+ */
4+#ifndef _UAPI_IOMMUFD_H
5+#define _UAPI_IOMMUFD_H
6+
7+#include <linux/types.h>
8+#include <linux/ioctl.h>
9+
10+#define IOMMUFD_TYPE (';')
11+
12+/**
13+ * DOC: General ioctl format
14+ *
15+ * The ioctl interface follows a general format to allow for extensibility. Each
16+ * ioctl is passed in a structure pointer as the argument providing the size of
17+ * the structure in the first u32. The kernel checks that any structure space
18+ * beyond what it understands is 0. This allows userspace to use the backward
19+ * compatible portion while consistently using the newer, larger, structures.
20+ *
21+ * ioctls use a standard meaning for common errnos:
22+ *
23+ * - ENOTTY: The IOCTL number itself is not supported at all
24+ * - E2BIG: The IOCTL number is supported, but the provided structure has
25+ * non-zero in a part the kernel does not understand.
26+ * - EOPNOTSUPP: The IOCTL number is supported, and the structure is
27+ * understood, however a known field has a value the kernel does not
28+ * understand or support.
29+ * - EINVAL: Everything about the IOCTL was understood, but a field is not
30+ * correct.
31+ * - ENOENT: An ID or IOVA provided does not exist.
32+ * - ENOMEM: Out of memory.
33+ * - EOVERFLOW: Mathematics overflowed.
34+ *
35+ * As well as additional errnos, within specific ioctls.
36+ */
37+enum {
38+ IOMMUFD_CMD_BASE = 0x80,
39+ IOMMUFD_CMD_DESTROY = IOMMUFD_CMD_BASE,
40+ IOMMUFD_CMD_IOAS_ALLOC,
41+ IOMMUFD_CMD_IOAS_ALLOW_IOVAS,
42+ IOMMUFD_CMD_IOAS_COPY,
43+ IOMMUFD_CMD_IOAS_IOVA_RANGES,
44+ IOMMUFD_CMD_IOAS_MAP,
45+ IOMMUFD_CMD_IOAS_UNMAP,
46+ IOMMUFD_CMD_OPTION,
47+ IOMMUFD_CMD_VFIO_IOAS,
48+};
49+
50+/**
51+ * struct iommu_destroy - ioctl(IOMMU_DESTROY)
52+ * @size: sizeof(struct iommu_destroy)
53+ * @id: iommufd object ID to destroy. Can be any destroyable object type.
54+ *
55+ * Destroy any object held within iommufd.
56+ */
57+struct iommu_destroy {
58+ __u32 size;
59+ __u32 id;
60+};
61+#define IOMMU_DESTROY _IO(IOMMUFD_TYPE, IOMMUFD_CMD_DESTROY)
62+
63+/**
64+ * struct iommu_ioas_alloc - ioctl(IOMMU_IOAS_ALLOC)
65+ * @size: sizeof(struct iommu_ioas_alloc)
66+ * @flags: Must be 0
67+ * @out_ioas_id: Output IOAS ID for the allocated object
68+ *
69+ * Allocate an IO Address Space (IOAS) which holds an IO Virtual Address (IOVA)
70+ * to memory mapping.
71+ */
72+struct iommu_ioas_alloc {
73+ __u32 size;
74+ __u32 flags;
75+ __u32 out_ioas_id;
76+};
77+#define IOMMU_IOAS_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_ALLOC)
78+
79+/**
80+ * struct iommu_iova_range - ioctl(IOMMU_IOVA_RANGE)
81+ * @start: First IOVA
82+ * @last: Inclusive last IOVA
83+ *
84+ * An interval in IOVA space.
85+ */
86+struct iommu_iova_range {
87+ __aligned_u64 start;
88+ __aligned_u64 last;
89+};
90+
91+/**
92+ * struct iommu_ioas_iova_ranges - ioctl(IOMMU_IOAS_IOVA_RANGES)
93+ * @size: sizeof(struct iommu_ioas_iova_ranges)
94+ * @ioas_id: IOAS ID to read ranges from
95+ * @num_iovas: Input/Output total number of ranges in the IOAS
96+ * @__reserved: Must be 0
97+ * @allowed_iovas: Pointer to the output array of struct iommu_iova_range
98+ * @out_iova_alignment: Minimum alignment required for mapping IOVA
99+ *
100+ * Query an IOAS for ranges of allowed IOVAs. Mapping IOVA outside these ranges
101+ * is not allowed. num_iovas will be set to the total number of iovas and
102+ * the allowed_iovas[] will be filled in as space permits.
103+ *
104+ * The allowed ranges are dependent on the HW path the DMA operation takes, and
105+ * can change during the lifetime of the IOAS. A fresh empty IOAS will have a
106+ * full range, and each attached device will narrow the ranges based on that
107+ * device's HW restrictions. Detaching a device can widen the ranges. Userspace
108+ * should query ranges after every attach/detach to know what IOVAs are valid
109+ * for mapping.
110+ *
111+ * On input num_iovas is the length of the allowed_iovas array. On output it is
112+ * the total number of iovas filled in. The ioctl will return -EMSGSIZE and set
113+ * num_iovas to the required value if num_iovas is too small. In this case the
114+ * caller should allocate a larger output array and re-issue the ioctl.
115+ *
116+ * out_iova_alignment returns the minimum IOVA alignment that can be given
117+ * to IOMMU_IOAS_MAP/COPY. IOVA's must satisfy::
118+ *
119+ * starting_iova % out_iova_alignment == 0
120+ * (starting_iova + length) % out_iova_alignment == 0
121+ *
122+ * out_iova_alignment can be 1 indicating any IOVA is allowed. It cannot
123+ * be higher than the system PAGE_SIZE.
124+ */
125+struct iommu_ioas_iova_ranges {
126+ __u32 size;
127+ __u32 ioas_id;
128+ __u32 num_iovas;
129+ __u32 __reserved;
130+ __aligned_u64 allowed_iovas;
131+ __aligned_u64 out_iova_alignment;
132+};
133+#define IOMMU_IOAS_IOVA_RANGES _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_IOVA_RANGES)
134+
135+/**
136+ * struct iommu_ioas_allow_iovas - ioctl(IOMMU_IOAS_ALLOW_IOVAS)
137+ * @size: sizeof(struct iommu_ioas_allow_iovas)
138+ * @ioas_id: IOAS ID to allow IOVAs from
139+ * @num_iovas: Input/Output total number of ranges in the IOAS
140+ * @__reserved: Must be 0
141+ * @allowed_iovas: Pointer to array of struct iommu_iova_range
142+ *
143+ * Ensure a range of IOVAs are always available for allocation. If this call
144+ * succeeds then IOMMU_IOAS_IOVA_RANGES will never return a list of IOVA ranges
145+ * that are narrower than the ranges provided here. This call will fail if
146+ * IOMMU_IOAS_IOVA_RANGES is currently narrower than the given ranges.
147+ *
148+ * When an IOAS is first created the IOVA_RANGES will be maximally sized, and as
149+ * devices are attached the IOVA will narrow based on the device restrictions.
150+ * When an allowed range is specified any narrowing will be refused, ie device
151+ * attachment can fail if the device requires limiting within the allowed range.
152+ *
153+ * Automatic IOVA allocation is also impacted by this call. MAP will only
154+ * allocate within the allowed IOVAs if they are present.
155+ *
156+ * This call replaces the entire allowed list with the given list.
157+ */
158+struct iommu_ioas_allow_iovas {
159+ __u32 size;
160+ __u32 ioas_id;
161+ __u32 num_iovas;
162+ __u32 __reserved;
163+ __aligned_u64 allowed_iovas;
164+};
165+#define IOMMU_IOAS_ALLOW_IOVAS _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_ALLOW_IOVAS)
166+
167+/**
168+ * enum iommufd_ioas_map_flags - Flags for map and copy
169+ * @IOMMU_IOAS_MAP_FIXED_IOVA: If clear the kernel will compute an appropriate
170+ * IOVA to place the mapping at
171+ * @IOMMU_IOAS_MAP_WRITEABLE: DMA is allowed to write to this mapping
172+ * @IOMMU_IOAS_MAP_READABLE: DMA is allowed to read from this mapping
173+ */
174+enum iommufd_ioas_map_flags {
175+ IOMMU_IOAS_MAP_FIXED_IOVA = 1 << 0,
176+ IOMMU_IOAS_MAP_WRITEABLE = 1 << 1,
177+ IOMMU_IOAS_MAP_READABLE = 1 << 2,
178+};
179+
180+/**
181+ * struct iommu_ioas_map - ioctl(IOMMU_IOAS_MAP)
182+ * @size: sizeof(struct iommu_ioas_map)
183+ * @flags: Combination of enum iommufd_ioas_map_flags
184+ * @ioas_id: IOAS ID to change the mapping of
185+ * @__reserved: Must be 0
186+ * @user_va: Userspace pointer to start mapping from
187+ * @length: Number of bytes to map
188+ * @iova: IOVA the mapping was placed at. If IOMMU_IOAS_MAP_FIXED_IOVA is set
189+ * then this must be provided as input.
190+ *
191+ * Set an IOVA mapping from a user pointer. If FIXED_IOVA is specified then the
192+ * mapping will be established at iova, otherwise a suitable location based on
193+ * the reserved and allowed lists will be automatically selected and returned in
194+ * iova.
195+ *
196+ * If IOMMU_IOAS_MAP_FIXED_IOVA is specified then the iova range must currently
197+ * be unused, existing IOVA cannot be replaced.
198+ */
199+struct iommu_ioas_map {
200+ __u32 size;
201+ __u32 flags;
202+ __u32 ioas_id;
203+ __u32 __reserved;
204+ __aligned_u64 user_va;
205+ __aligned_u64 length;
206+ __aligned_u64 iova;
207+};
208+#define IOMMU_IOAS_MAP _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_MAP)
209+
210+/**
211+ * struct iommu_ioas_copy - ioctl(IOMMU_IOAS_COPY)
212+ * @size: sizeof(struct iommu_ioas_copy)
213+ * @flags: Combination of enum iommufd_ioas_map_flags
214+ * @dst_ioas_id: IOAS ID to change the mapping of
215+ * @src_ioas_id: IOAS ID to copy from
216+ * @length: Number of bytes to copy and map
217+ * @dst_iova: IOVA the mapping was placed at. If IOMMU_IOAS_MAP_FIXED_IOVA is
218+ * set then this must be provided as input.
219+ * @src_iova: IOVA to start the copy
220+ *
221+ * Copy an already existing mapping from src_ioas_id and establish it in
222+ * dst_ioas_id. The src iova/length must exactly match a range used with
223+ * IOMMU_IOAS_MAP.
224+ *
225+ * This may be used to efficiently clone a subset of an IOAS to another, or as a
226+ * kind of 'cache' to speed up mapping. Copy has an efficiency advantage over
227+ * establishing equivalent new mappings, as internal resources are shared, and
228+ * the kernel will pin the user memory only once.
229+ */
230+struct iommu_ioas_copy {
231+ __u32 size;
232+ __u32 flags;
233+ __u32 dst_ioas_id;
234+ __u32 src_ioas_id;
235+ __aligned_u64 length;
236+ __aligned_u64 dst_iova;
237+ __aligned_u64 src_iova;
238+};
239+#define IOMMU_IOAS_COPY _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_COPY)
240+
241+/**
242+ * struct iommu_ioas_unmap - ioctl(IOMMU_IOAS_UNMAP)
243+ * @size: sizeof(struct iommu_ioas_unmap)
244+ * @ioas_id: IOAS ID to change the mapping of
245+ * @iova: IOVA to start the unmapping at
246+ * @length: Number of bytes to unmap, and return back the bytes unmapped
247+ *
248+ * Unmap an IOVA range. The iova/length must be a superset of a previously
249+ * mapped range used with IOMMU_IOAS_MAP or IOMMU_IOAS_COPY. Splitting or
250+ * truncating ranges is not allowed. The values 0 to U64_MAX will unmap
251+ * everything.
252+ */
253+struct iommu_ioas_unmap {
254+ __u32 size;
255+ __u32 ioas_id;
256+ __aligned_u64 iova;
257+ __aligned_u64 length;
258+};
259+#define IOMMU_IOAS_UNMAP _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_UNMAP)
260+
261+/**
262+ * enum iommufd_option - ioctl(IOMMU_OPTION_RLIMIT_MODE) and
263+ * ioctl(IOMMU_OPTION_HUGE_PAGES)
264+ * @IOMMU_OPTION_RLIMIT_MODE:
265+ * Change how RLIMIT_MEMLOCK accounting works. The caller must have privilege
266+ * to invoke this. Value 0 (default) is user based accouting, 1 uses process
267+ * based accounting. Global option, object_id must be 0
268+ * @IOMMU_OPTION_HUGE_PAGES:
269+ * Value 1 (default) allows contiguous pages to be combined when generating
270+ * iommu mappings. Value 0 disables combining, everything is mapped to
271+ * PAGE_SIZE. This can be useful for benchmarking. This is a per-IOAS
272+ * option, the object_id must be the IOAS ID.
273+ */
274+enum iommufd_option {
275+ IOMMU_OPTION_RLIMIT_MODE = 0,
276+ IOMMU_OPTION_HUGE_PAGES = 1,
277+};
278+
279+/**
280+ * enum iommufd_option_ops - ioctl(IOMMU_OPTION_OP_SET) and
281+ * ioctl(IOMMU_OPTION_OP_GET)
282+ * @IOMMU_OPTION_OP_SET: Set the option's value
283+ * @IOMMU_OPTION_OP_GET: Get the option's value
284+ */
285+enum iommufd_option_ops {
286+ IOMMU_OPTION_OP_SET = 0,
287+ IOMMU_OPTION_OP_GET = 1,
288+};
289+
290+/**
291+ * struct iommu_option - iommu option multiplexer
292+ * @size: sizeof(struct iommu_option)
293+ * @option_id: One of enum iommufd_option
294+ * @op: One of enum iommufd_option_ops
295+ * @__reserved: Must be 0
296+ * @object_id: ID of the object if required
297+ * @val64: Option value to set or value returned on get
298+ *
299+ * Change a simple option value. This multiplexor allows controlling options
300+ * on objects. IOMMU_OPTION_OP_SET will load an option and IOMMU_OPTION_OP_GET
301+ * will return the current value.
302+ */
303+struct iommu_option {
304+ __u32 size;
305+ __u32 option_id;
306+ __u16 op;
307+ __u16 __reserved;
308+ __u32 object_id;
309+ __aligned_u64 val64;
310+};
311+#define IOMMU_OPTION _IO(IOMMUFD_TYPE, IOMMUFD_CMD_OPTION)
312+
313+/**
314+ * enum iommufd_vfio_ioas_op - IOMMU_VFIO_IOAS_* ioctls
315+ * @IOMMU_VFIO_IOAS_GET: Get the current compatibility IOAS
316+ * @IOMMU_VFIO_IOAS_SET: Change the current compatibility IOAS
317+ * @IOMMU_VFIO_IOAS_CLEAR: Disable VFIO compatibility
318+ */
319+enum iommufd_vfio_ioas_op {
320+ IOMMU_VFIO_IOAS_GET = 0,
321+ IOMMU_VFIO_IOAS_SET = 1,
322+ IOMMU_VFIO_IOAS_CLEAR = 2,
323+};
324+
325+/**
326+ * struct iommu_vfio_ioas - ioctl(IOMMU_VFIO_IOAS)
327+ * @size: sizeof(struct iommu_vfio_ioas)
328+ * @ioas_id: For IOMMU_VFIO_IOAS_SET the input IOAS ID to set
329+ * For IOMMU_VFIO_IOAS_GET will output the IOAS ID
330+ * @op: One of enum iommufd_vfio_ioas_op
331+ * @__reserved: Must be 0
332+ *
333+ * The VFIO compatibility support uses a single ioas because VFIO APIs do not
334+ * support the ID field. Set or Get the IOAS that VFIO compatibility will use.
335+ * When VFIO_GROUP_SET_CONTAINER is used on an iommufd it will get the
336+ * compatibility ioas, either by taking what is already set, or auto creating
337+ * one. From then on VFIO will continue to use that ioas and is not effected by
338+ * this ioctl. SET or CLEAR does not destroy any auto-created IOAS.
339+ */
340+struct iommu_vfio_ioas {
341+ __u32 size;
342+ __u32 ioas_id;
343+ __u16 op;
344+ __u16 __reserved;
345+};
346+#define IOMMU_VFIO_IOAS _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VFIO_IOAS)
347+#endif