1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ |
2 | #ifndef _UAPI_VDUSE_H_ |
3 | #define _UAPI_VDUSE_H_ |
4 | |
5 | #include <linux/types.h> |
6 | |
7 | #define VDUSE_BASE 0x81 |
8 | |
9 | /* The ioctls for control device (/dev/vduse/control) */ |
10 | |
11 | #define VDUSE_API_VERSION 0 |
12 | |
13 | /* |
14 | * Get the version of VDUSE API that kernel supported (VDUSE_API_VERSION). |
15 | * This is used for future extension. |
16 | */ |
17 | #define VDUSE_GET_API_VERSION _IOR(VDUSE_BASE, 0x00, __u64) |
18 | |
19 | /* Set the version of VDUSE API that userspace supported. */ |
20 | #define VDUSE_SET_API_VERSION _IOW(VDUSE_BASE, 0x01, __u64) |
21 | |
22 | /** |
23 | * struct vduse_dev_config - basic configuration of a VDUSE device |
24 | * @name: VDUSE device name, needs to be NUL terminated |
25 | * @vendor_id: virtio vendor id |
26 | * @device_id: virtio device id |
27 | * @features: virtio features |
28 | * @vq_num: the number of virtqueues |
29 | * @vq_align: the allocation alignment of virtqueue's metadata |
30 | * @reserved: for future use, needs to be initialized to zero |
31 | * @config_size: the size of the configuration space |
32 | * @config: the buffer of the configuration space |
33 | * |
34 | * Structure used by VDUSE_CREATE_DEV ioctl to create VDUSE device. |
35 | */ |
36 | struct vduse_dev_config { |
37 | #define VDUSE_NAME_MAX 256 |
38 | char name[VDUSE_NAME_MAX]; |
39 | __u32 vendor_id; |
40 | __u32 device_id; |
41 | __u64 features; |
42 | __u32 vq_num; |
43 | __u32 vq_align; |
44 | __u32 reserved[13]; |
45 | __u32 config_size; |
46 | __u8 config[]; |
47 | }; |
48 | |
49 | /* Create a VDUSE device which is represented by a char device (/dev/vduse/$NAME) */ |
50 | #define VDUSE_CREATE_DEV _IOW(VDUSE_BASE, 0x02, struct vduse_dev_config) |
51 | |
52 | /* |
53 | * Destroy a VDUSE device. Make sure there are no more references |
54 | * to the char device (/dev/vduse/$NAME). |
55 | */ |
56 | #define VDUSE_DESTROY_DEV _IOW(VDUSE_BASE, 0x03, char[VDUSE_NAME_MAX]) |
57 | |
58 | /* The ioctls for VDUSE device (/dev/vduse/$NAME) */ |
59 | |
60 | /** |
61 | * struct vduse_iotlb_entry - entry of IOTLB to describe one IOVA region [start, last] |
62 | * @offset: the mmap offset on returned file descriptor |
63 | * @start: start of the IOVA region |
64 | * @last: last of the IOVA region |
65 | * @perm: access permission of the IOVA region |
66 | * |
67 | * Structure used by VDUSE_IOTLB_GET_FD ioctl to find an overlapped IOVA region. |
68 | */ |
69 | struct vduse_iotlb_entry { |
70 | __u64 offset; |
71 | __u64 start; |
72 | __u64 last; |
73 | #define VDUSE_ACCESS_RO 0x1 |
74 | #define VDUSE_ACCESS_WO 0x2 |
75 | #define VDUSE_ACCESS_RW 0x3 |
76 | __u8 perm; |
77 | }; |
78 | |
79 | /* |
80 | * Find the first IOVA region that overlaps with the range [start, last] |
81 | * and return the corresponding file descriptor. Return -EINVAL means the |
82 | * IOVA region doesn't exist. Caller should set start and last fields. |
83 | */ |
84 | #define VDUSE_IOTLB_GET_FD _IOWR(VDUSE_BASE, 0x10, struct vduse_iotlb_entry) |
85 | |
86 | /* |
87 | * Get the negotiated virtio features. It's a subset of the features in |
88 | * struct vduse_dev_config which can be accepted by virtio driver. It's |
89 | * only valid after FEATURES_OK status bit is set. |
90 | */ |
91 | #define VDUSE_DEV_GET_FEATURES _IOR(VDUSE_BASE, 0x11, __u64) |
92 | |
93 | /** |
94 | * struct vduse_config_data - data used to update configuration space |
95 | * @offset: the offset from the beginning of configuration space |
96 | * @length: the length to write to configuration space |
97 | * @buffer: the buffer used to write from |
98 | * |
99 | * Structure used by VDUSE_DEV_SET_CONFIG ioctl to update device |
100 | * configuration space. |
101 | */ |
102 | struct vduse_config_data { |
103 | __u32 offset; |
104 | __u32 length; |
105 | __u8 buffer[]; |
106 | }; |
107 | |
108 | /* Set device configuration space */ |
109 | #define VDUSE_DEV_SET_CONFIG _IOW(VDUSE_BASE, 0x12, struct vduse_config_data) |
110 | |
111 | /* |
112 | * Inject a config interrupt. It's usually used to notify virtio driver |
113 | * that device configuration space has changed. |
114 | */ |
115 | #define VDUSE_DEV_INJECT_CONFIG_IRQ _IO(VDUSE_BASE, 0x13) |
116 | |
117 | /** |
118 | * struct vduse_vq_config - basic configuration of a virtqueue |
119 | * @index: virtqueue index |
120 | * @max_size: the max size of virtqueue |
121 | * @reserved: for future use, needs to be initialized to zero |
122 | * |
123 | * Structure used by VDUSE_VQ_SETUP ioctl to setup a virtqueue. |
124 | */ |
125 | struct vduse_vq_config { |
126 | __u32 index; |
127 | __u16 max_size; |
128 | __u16 reserved[13]; |
129 | }; |
130 | |
131 | /* |
132 | * Setup the specified virtqueue. Make sure all virtqueues have been |
133 | * configured before the device is attached to vDPA bus. |
134 | */ |
135 | #define VDUSE_VQ_SETUP _IOW(VDUSE_BASE, 0x14, struct vduse_vq_config) |
136 | |
137 | /** |
138 | * struct vduse_vq_state_split - split virtqueue state |
139 | * @avail_index: available index |
140 | */ |
141 | struct vduse_vq_state_split { |
142 | __u16 avail_index; |
143 | }; |
144 | |
145 | /** |
146 | * struct vduse_vq_state_packed - packed virtqueue state |
147 | * @last_avail_counter: last driver ring wrap counter observed by device |
148 | * @last_avail_idx: device available index |
149 | * @last_used_counter: device ring wrap counter |
150 | * @last_used_idx: used index |
151 | */ |
152 | struct vduse_vq_state_packed { |
153 | __u16 last_avail_counter; |
154 | __u16 last_avail_idx; |
155 | __u16 last_used_counter; |
156 | __u16 last_used_idx; |
157 | }; |
158 | |
159 | /** |
160 | * struct vduse_vq_info - information of a virtqueue |
161 | * @index: virtqueue index |
162 | * @num: the size of virtqueue |
163 | * @desc_addr: address of desc area |
164 | * @driver_addr: address of driver area |
165 | * @device_addr: address of device area |
166 | * @split: split virtqueue state |
167 | * @packed: packed virtqueue state |
168 | * @ready: ready status of virtqueue |
169 | * |
170 | * Structure used by VDUSE_VQ_GET_INFO ioctl to get virtqueue's information. |
171 | */ |
172 | struct vduse_vq_info { |
173 | __u32 index; |
174 | __u32 num; |
175 | __u64 desc_addr; |
176 | __u64 driver_addr; |
177 | __u64 device_addr; |
178 | union { |
179 | struct vduse_vq_state_split split; |
180 | struct vduse_vq_state_packed packed; |
181 | }; |
182 | __u8 ready; |
183 | }; |
184 | |
185 | /* Get the specified virtqueue's information. Caller should set index field. */ |
186 | #define VDUSE_VQ_GET_INFO _IOWR(VDUSE_BASE, 0x15, struct vduse_vq_info) |
187 | |
188 | /** |
189 | * struct vduse_vq_eventfd - eventfd configuration for a virtqueue |
190 | * @index: virtqueue index |
191 | * @fd: eventfd, -1 means de-assigning the eventfd |
192 | * |
193 | * Structure used by VDUSE_VQ_SETUP_KICKFD ioctl to setup kick eventfd. |
194 | */ |
195 | struct vduse_vq_eventfd { |
196 | __u32 index; |
197 | #define VDUSE_EVENTFD_DEASSIGN -1 |
198 | int fd; |
199 | }; |
200 | |
201 | /* |
202 | * Setup kick eventfd for specified virtqueue. The kick eventfd is used |
203 | * by VDUSE kernel module to notify userspace to consume the avail vring. |
204 | */ |
205 | #define VDUSE_VQ_SETUP_KICKFD _IOW(VDUSE_BASE, 0x16, struct vduse_vq_eventfd) |
206 | |
207 | /* |
208 | * Inject an interrupt for specific virtqueue. It's used to notify virtio driver |
209 | * to consume the used vring. |
210 | */ |
211 | #define VDUSE_VQ_INJECT_IRQ _IOW(VDUSE_BASE, 0x17, __u32) |
212 | |
213 | /** |
214 | * struct vduse_iova_umem - userspace memory configuration for one IOVA region |
215 | * @uaddr: start address of userspace memory, it must be aligned to page size |
216 | * @iova: start of the IOVA region |
217 | * @size: size of the IOVA region |
218 | * @reserved: for future use, needs to be initialized to zero |
219 | * |
220 | * Structure used by VDUSE_IOTLB_REG_UMEM and VDUSE_IOTLB_DEREG_UMEM |
221 | * ioctls to register/de-register userspace memory for IOVA regions |
222 | */ |
223 | struct vduse_iova_umem { |
224 | __u64 uaddr; |
225 | __u64 iova; |
226 | __u64 size; |
227 | __u64 reserved[3]; |
228 | }; |
229 | |
230 | /* Register userspace memory for IOVA regions */ |
231 | #define VDUSE_IOTLB_REG_UMEM _IOW(VDUSE_BASE, 0x18, struct vduse_iova_umem) |
232 | |
233 | /* De-register the userspace memory. Caller should set iova and size field. */ |
234 | #define VDUSE_IOTLB_DEREG_UMEM _IOW(VDUSE_BASE, 0x19, struct vduse_iova_umem) |
235 | |
236 | /** |
237 | * struct vduse_iova_info - information of one IOVA region |
238 | * @start: start of the IOVA region |
239 | * @last: last of the IOVA region |
240 | * @capability: capability of the IOVA regsion |
241 | * @reserved: for future use, needs to be initialized to zero |
242 | * |
243 | * Structure used by VDUSE_IOTLB_GET_INFO ioctl to get information of |
244 | * one IOVA region. |
245 | */ |
246 | struct vduse_iova_info { |
247 | __u64 start; |
248 | __u64 last; |
249 | #define VDUSE_IOVA_CAP_UMEM (1 << 0) |
250 | __u64 capability; |
251 | __u64 reserved[3]; |
252 | }; |
253 | |
254 | /* |
255 | * Find the first IOVA region that overlaps with the range [start, last] |
256 | * and return some information on it. Caller should set start and last fields. |
257 | */ |
258 | #define VDUSE_IOTLB_GET_INFO _IOWR(VDUSE_BASE, 0x1a, struct vduse_iova_info) |
259 | |
260 | /* The control messages definition for read(2)/write(2) on /dev/vduse/$NAME */ |
261 | |
262 | /** |
263 | * enum vduse_req_type - request type |
264 | * @VDUSE_GET_VQ_STATE: get the state for specified virtqueue from userspace |
265 | * @VDUSE_SET_STATUS: set the device status |
266 | * @VDUSE_UPDATE_IOTLB: Notify userspace to update the memory mapping for |
267 | * specified IOVA range via VDUSE_IOTLB_GET_FD ioctl |
268 | */ |
269 | enum vduse_req_type { |
270 | VDUSE_GET_VQ_STATE, |
271 | VDUSE_SET_STATUS, |
272 | VDUSE_UPDATE_IOTLB, |
273 | }; |
274 | |
275 | /** |
276 | * struct vduse_vq_state - virtqueue state |
277 | * @index: virtqueue index |
278 | * @split: split virtqueue state |
279 | * @packed: packed virtqueue state |
280 | */ |
281 | struct vduse_vq_state { |
282 | __u32 index; |
283 | union { |
284 | struct vduse_vq_state_split split; |
285 | struct vduse_vq_state_packed packed; |
286 | }; |
287 | }; |
288 | |
289 | /** |
290 | * struct vduse_dev_status - device status |
291 | * @status: device status |
292 | */ |
293 | struct vduse_dev_status { |
294 | __u8 status; |
295 | }; |
296 | |
297 | /** |
298 | * struct vduse_iova_range - IOVA range [start, last] |
299 | * @start: start of the IOVA range |
300 | * @last: last of the IOVA range |
301 | */ |
302 | struct vduse_iova_range { |
303 | __u64 start; |
304 | __u64 last; |
305 | }; |
306 | |
307 | /** |
308 | * struct vduse_dev_request - control request |
309 | * @type: request type |
310 | * @request_id: request id |
311 | * @reserved: for future use |
312 | * @vq_state: virtqueue state, only index field is available |
313 | * @s: device status |
314 | * @iova: IOVA range for updating |
315 | * @padding: padding |
316 | * |
317 | * Structure used by read(2) on /dev/vduse/$NAME. |
318 | */ |
319 | struct vduse_dev_request { |
320 | __u32 type; |
321 | __u32 request_id; |
322 | __u32 reserved[4]; |
323 | union { |
324 | struct vduse_vq_state vq_state; |
325 | struct vduse_dev_status s; |
326 | struct vduse_iova_range iova; |
327 | __u32 padding[32]; |
328 | }; |
329 | }; |
330 | |
331 | /** |
332 | * struct vduse_dev_response - response to control request |
333 | * @request_id: corresponding request id |
334 | * @result: the result of request |
335 | * @reserved: for future use, needs to be initialized to zero |
336 | * @vq_state: virtqueue state |
337 | * @padding: padding |
338 | * |
339 | * Structure used by write(2) on /dev/vduse/$NAME. |
340 | */ |
341 | struct vduse_dev_response { |
342 | __u32 request_id; |
343 | #define VDUSE_REQ_RESULT_OK 0x00 |
344 | #define VDUSE_REQ_RESULT_FAILED 0x01 |
345 | __u32 result; |
346 | __u32 reserved[4]; |
347 | union { |
348 | struct vduse_vq_state vq_state; |
349 | __u32 padding[32]; |
350 | }; |
351 | }; |
352 | |
353 | #endif /* _UAPI_VDUSE_H_ */ |
354 | |