History

vduse: Introduce VDUSE - vDPA Device in Userspace

This VDUSE driver enables implementing software-emulated vDPA devices in userspace. The vDPA device is created by ioctl(VDUSE_CREATE_DEV) on /dev/vduse/control. Then a char device interface (/dev/vduse/$NAME) is exported to userspace for device emulation. In order to make the device emulation more secure, the device's control path is handled in kernel. A message mechnism is introduced to forward some dataplane related control messages to userspace. And in the data path, the DMA buffer will be mapped into userspace address space through different ways depending on the vDPA bus to which the vDPA device is attached. In virtio-vdpa case, the MMU-based software IOTLB is used to achieve that. And in vhost-vdpa case, the DMA buffer is reside in a userspace memory region which can be shared to the VDUSE userspace processs via transferring the shmfd. For more details on VDUSE design and usage, please see the follow-on Documentation commit. NB(mst): when merging this with b542e383d8c0 ("eventfd: Make signal recursion protection a task bit") replace eventfd_signal_count with eventfd_signal_allowed, and drop the previous ("eventfd: Export eventfd_wake_count to modules").

Xie Yongji committed 5 years ago

Commit c8a61531 parent 8c773d56 files · +1969 −0Browse files

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

Unified · Split

include/uapi/linux/vduse.h+306−0
@@ -0,0 +1,306 @@
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 */
36struct 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 */
69struct 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 */
102struct 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 */
125struct 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 */
141struct 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 */
152struct 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 */
172struct 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 */
195struct 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/* The control messages definition for read(2)/write(2) on /dev/vduse/$NAME */
214
215/**
216 * enum vduse_req_type - request type
217 * @VDUSE_GET_VQ_STATE: get the state for specified virtqueue from userspace
218 * @VDUSE_SET_STATUS: set the device status
219 * @VDUSE_UPDATE_IOTLB: Notify userspace to update the memory mapping for
220 * specified IOVA range via VDUSE_IOTLB_GET_FD ioctl
221 */
222enum vduse_req_type {
223 VDUSE_GET_VQ_STATE,
224 VDUSE_SET_STATUS,
225 VDUSE_UPDATE_IOTLB,
226};
227
228/**
229 * struct vduse_vq_state - virtqueue state
230 * @index: virtqueue index
231 * @split: split virtqueue state
232 * @packed: packed virtqueue state
233 */
234struct vduse_vq_state {
235 __u32 index;
236 union {
237 struct vduse_vq_state_split split;
238 struct vduse_vq_state_packed packed;
239 };
240};
241
242/**
243 * struct vduse_dev_status - device status
244 * @status: device status
245 */
246struct vduse_dev_status {
247 __u8 status;
248};
249
250/**
251 * struct vduse_iova_range - IOVA range [start, last]
252 * @start: start of the IOVA range
253 * @last: last of the IOVA range
254 */
255struct vduse_iova_range {
256 __u64 start;
257 __u64 last;
258};
259
260/**
261 * struct vduse_dev_request - control request
262 * @type: request type
263 * @request_id: request id
264 * @reserved: for future use
265 * @vq_state: virtqueue state, only index field is available
266 * @s: device status
267 * @iova: IOVA range for updating
268 * @padding: padding
269 *
270 * Structure used by read(2) on /dev/vduse/$NAME.
271 */
272struct vduse_dev_request {
273 __u32 type;
274 __u32 request_id;
275 __u32 reserved[4];
276 union {
277 struct vduse_vq_state vq_state;
278 struct vduse_dev_status s;
279 struct vduse_iova_range iova;
280 __u32 padding[32];
281 };
282};
283
284/**
285 * struct vduse_dev_response - response to control request
286 * @request_id: corresponding request id
287 * @result: the result of request
288 * @reserved: for future use, needs to be initialized to zero
289 * @vq_state: virtqueue state
290 * @padding: padding
291 *
292 * Structure used by write(2) on /dev/vduse/$NAME.
293 */
294struct vduse_dev_response {
295 __u32 request_id;
296#define VDUSE_REQ_RESULT_OK 0x00
297#define VDUSE_REQ_RESULT_FAILED 0x01
298 __u32 result;
299 __u32 reserved[4];
300 union {
301 struct vduse_vq_state vq_state;
302 __u32 padding[32];
303 };
304};
305
306#endif /* _UAPI_VDUSE_H_ */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t