xref: /linux-6.15/include/linux/iommufd.h (revision 941d0719)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2021 Intel Corporation
4  * Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES
5  */
6 #ifndef __LINUX_IOMMUFD_H
7 #define __LINUX_IOMMUFD_H
8 
9 #include <linux/err.h>
10 #include <linux/errno.h>
11 #include <linux/refcount.h>
12 #include <linux/types.h>
13 #include <linux/xarray.h>
14 #include <uapi/linux/iommufd.h>
15 
16 struct device;
17 struct file;
18 struct iommu_group;
19 struct iommu_user_data;
20 struct iommu_user_data_array;
21 struct iommufd_access;
22 struct iommufd_ctx;
23 struct iommufd_device;
24 struct iommufd_viommu_ops;
25 struct page;
26 
27 enum iommufd_object_type {
28 	IOMMUFD_OBJ_NONE,
29 	IOMMUFD_OBJ_ANY = IOMMUFD_OBJ_NONE,
30 	IOMMUFD_OBJ_DEVICE,
31 	IOMMUFD_OBJ_HWPT_PAGING,
32 	IOMMUFD_OBJ_HWPT_NESTED,
33 	IOMMUFD_OBJ_IOAS,
34 	IOMMUFD_OBJ_ACCESS,
35 	IOMMUFD_OBJ_FAULT,
36 	IOMMUFD_OBJ_VIOMMU,
37 	IOMMUFD_OBJ_VDEVICE,
38 	IOMMUFD_OBJ_VEVENTQ,
39 #ifdef CONFIG_IOMMUFD_TEST
40 	IOMMUFD_OBJ_SELFTEST,
41 #endif
42 	IOMMUFD_OBJ_MAX,
43 };
44 
45 /* Base struct for all objects with a userspace ID handle. */
46 struct iommufd_object {
47 	refcount_t shortterm_users;
48 	refcount_t users;
49 	enum iommufd_object_type type;
50 	unsigned int id;
51 };
52 
53 struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
54 					   struct device *dev, u32 *id);
55 void iommufd_device_unbind(struct iommufd_device *idev);
56 
57 int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id);
58 int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id);
59 void iommufd_device_detach(struct iommufd_device *idev);
60 
61 struct iommufd_ctx *iommufd_device_to_ictx(struct iommufd_device *idev);
62 u32 iommufd_device_to_id(struct iommufd_device *idev);
63 
64 struct iommufd_access_ops {
65 	u8 needs_pin_pages : 1;
66 	void (*unmap)(void *data, unsigned long iova, unsigned long length);
67 };
68 
69 enum {
70 	IOMMUFD_ACCESS_RW_READ = 0,
71 	IOMMUFD_ACCESS_RW_WRITE = 1 << 0,
72 	/* Set if the caller is in a kthread then rw will use kthread_use_mm() */
73 	IOMMUFD_ACCESS_RW_KTHREAD = 1 << 1,
74 
75 	/* Only for use by selftest */
76 	__IOMMUFD_ACCESS_RW_SLOW_PATH = 1 << 2,
77 };
78 
79 struct iommufd_access *
80 iommufd_access_create(struct iommufd_ctx *ictx,
81 		      const struct iommufd_access_ops *ops, void *data, u32 *id);
82 void iommufd_access_destroy(struct iommufd_access *access);
83 int iommufd_access_attach(struct iommufd_access *access, u32 ioas_id);
84 int iommufd_access_replace(struct iommufd_access *access, u32 ioas_id);
85 void iommufd_access_detach(struct iommufd_access *access);
86 
87 void iommufd_ctx_get(struct iommufd_ctx *ictx);
88 
89 struct iommufd_viommu {
90 	struct iommufd_object obj;
91 	struct iommufd_ctx *ictx;
92 	struct iommu_device *iommu_dev;
93 	struct iommufd_hwpt_paging *hwpt;
94 
95 	const struct iommufd_viommu_ops *ops;
96 
97 	struct xarray vdevs;
98 	struct list_head veventqs;
99 	struct rw_semaphore veventqs_rwsem;
100 
101 	unsigned int type;
102 };
103 
104 /**
105  * struct iommufd_viommu_ops - vIOMMU specific operations
106  * @destroy: Clean up all driver-specific parts of an iommufd_viommu. The memory
107  *           of the vIOMMU will be free-ed by iommufd core after calling this op
108  * @alloc_domain_nested: Allocate a IOMMU_DOMAIN_NESTED on a vIOMMU that holds a
109  *                       nesting parent domain (IOMMU_DOMAIN_PAGING). @user_data
110  *                       must be defined in include/uapi/linux/iommufd.h.
111  *                       It must fully initialize the new iommu_domain before
112  *                       returning. Upon failure, ERR_PTR must be returned.
113  * @cache_invalidate: Flush hardware cache used by a vIOMMU. It can be used for
114  *                    any IOMMU hardware specific cache: TLB and device cache.
115  *                    The @array passes in the cache invalidation requests, in
116  *                    form of a driver data structure. A driver must update the
117  *                    array->entry_num to report the number of handled requests.
118  *                    The data structure of the array entry must be defined in
119  *                    include/uapi/linux/iommufd.h
120  */
121 struct iommufd_viommu_ops {
122 	void (*destroy)(struct iommufd_viommu *viommu);
123 	struct iommu_domain *(*alloc_domain_nested)(
124 		struct iommufd_viommu *viommu, u32 flags,
125 		const struct iommu_user_data *user_data);
126 	int (*cache_invalidate)(struct iommufd_viommu *viommu,
127 				struct iommu_user_data_array *array);
128 };
129 
130 #if IS_ENABLED(CONFIG_IOMMUFD)
131 struct iommufd_ctx *iommufd_ctx_from_file(struct file *file);
132 struct iommufd_ctx *iommufd_ctx_from_fd(int fd);
133 void iommufd_ctx_put(struct iommufd_ctx *ictx);
134 bool iommufd_ctx_has_group(struct iommufd_ctx *ictx, struct iommu_group *group);
135 
136 int iommufd_access_pin_pages(struct iommufd_access *access, unsigned long iova,
137 			     unsigned long length, struct page **out_pages,
138 			     unsigned int flags);
139 void iommufd_access_unpin_pages(struct iommufd_access *access,
140 				unsigned long iova, unsigned long length);
141 int iommufd_access_rw(struct iommufd_access *access, unsigned long iova,
142 		      void *data, size_t len, unsigned int flags);
143 int iommufd_vfio_compat_ioas_get_id(struct iommufd_ctx *ictx, u32 *out_ioas_id);
144 int iommufd_vfio_compat_ioas_create(struct iommufd_ctx *ictx);
145 int iommufd_vfio_compat_set_no_iommu(struct iommufd_ctx *ictx);
146 #else /* !CONFIG_IOMMUFD */
147 static inline struct iommufd_ctx *iommufd_ctx_from_file(struct file *file)
148 {
149 	return ERR_PTR(-EOPNOTSUPP);
150 }
151 
152 static inline void iommufd_ctx_put(struct iommufd_ctx *ictx)
153 {
154 }
155 
156 static inline int iommufd_access_pin_pages(struct iommufd_access *access,
157 					   unsigned long iova,
158 					   unsigned long length,
159 					   struct page **out_pages,
160 					   unsigned int flags)
161 {
162 	return -EOPNOTSUPP;
163 }
164 
165 static inline void iommufd_access_unpin_pages(struct iommufd_access *access,
166 					      unsigned long iova,
167 					      unsigned long length)
168 {
169 }
170 
171 static inline int iommufd_access_rw(struct iommufd_access *access, unsigned long iova,
172 		      void *data, size_t len, unsigned int flags)
173 {
174 	return -EOPNOTSUPP;
175 }
176 
177 static inline int iommufd_vfio_compat_ioas_create(struct iommufd_ctx *ictx)
178 {
179 	return -EOPNOTSUPP;
180 }
181 
182 static inline int iommufd_vfio_compat_set_no_iommu(struct iommufd_ctx *ictx)
183 {
184 	return -EOPNOTSUPP;
185 }
186 #endif /* CONFIG_IOMMUFD */
187 
188 #if IS_ENABLED(CONFIG_IOMMUFD_DRIVER_CORE)
189 struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
190 					     size_t size,
191 					     enum iommufd_object_type type);
192 struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
193 				       unsigned long vdev_id);
194 int iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
195 			       struct device *dev, unsigned long *vdev_id);
196 int iommufd_viommu_report_event(struct iommufd_viommu *viommu,
197 				enum iommu_veventq_type type, void *event_data,
198 				size_t data_len);
199 #else /* !CONFIG_IOMMUFD_DRIVER_CORE */
200 static inline struct iommufd_object *
201 _iommufd_object_alloc(struct iommufd_ctx *ictx, size_t size,
202 		      enum iommufd_object_type type)
203 {
204 	return ERR_PTR(-EOPNOTSUPP);
205 }
206 
207 static inline struct device *
208 iommufd_viommu_find_dev(struct iommufd_viommu *viommu, unsigned long vdev_id)
209 {
210 	return NULL;
211 }
212 
213 static inline int iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
214 					     struct device *dev,
215 					     unsigned long *vdev_id)
216 {
217 	return -ENOENT;
218 }
219 
220 static inline int iommufd_viommu_report_event(struct iommufd_viommu *viommu,
221 					      enum iommu_veventq_type type,
222 					      void *event_data, size_t data_len)
223 {
224 	return -EOPNOTSUPP;
225 }
226 #endif /* CONFIG_IOMMUFD_DRIVER_CORE */
227 
228 /*
229  * Helpers for IOMMU driver to allocate driver structures that will be freed by
230  * the iommufd core. The free op will be called prior to freeing the memory.
231  */
232 #define iommufd_viommu_alloc(ictx, drv_struct, member, viommu_ops)             \
233 	({                                                                     \
234 		drv_struct *ret;                                               \
235 									       \
236 		static_assert(__same_type(struct iommufd_viommu,               \
237 					  ((drv_struct *)NULL)->member));      \
238 		static_assert(offsetof(drv_struct, member.obj) == 0);          \
239 		ret = (drv_struct *)_iommufd_object_alloc(                     \
240 			ictx, sizeof(drv_struct), IOMMUFD_OBJ_VIOMMU);         \
241 		if (!IS_ERR(ret))                                              \
242 			ret->member.ops = viommu_ops;                          \
243 		ret;                                                           \
244 	})
245 #endif
246