1 /* 2 * VDUSE (vDPA Device in Userspace) library 3 * 4 * Copyright (C) 2022 Bytedance Inc. and/or its affiliates. All rights reserved. 5 * 6 * Author: 7 * Xie Yongji <xieyongji@bytedance.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or 10 * later. See the COPYING file in the top-level directory. 11 */ 12 13 #ifndef LIBVDUSE_H 14 #define LIBVDUSE_H 15 16 #include <stdint.h> 17 #include <sys/uio.h> 18 19 #define VIRTQUEUE_MAX_SIZE 1024 20 21 /* VDUSE device structure */ 22 typedef struct VduseDev VduseDev; 23 24 /* Virtqueue structure */ 25 typedef struct VduseVirtq VduseVirtq; 26 27 /* Some operation of VDUSE backend */ 28 typedef struct VduseOps { 29 /* Called when virtqueue can be processed */ 30 void (*enable_queue)(VduseDev *dev, VduseVirtq *vq); 31 /* Called when virtqueue processing should be stopped */ 32 void (*disable_queue)(VduseDev *dev, VduseVirtq *vq); 33 } VduseOps; 34 35 /* Describing elements of the I/O buffer */ 36 typedef struct VduseVirtqElement { 37 /* Descriptor table index */ 38 unsigned int index; 39 /* Number of physically-contiguous device-readable descriptors */ 40 unsigned int out_num; 41 /* Number of physically-contiguous device-writable descriptors */ 42 unsigned int in_num; 43 /* Array to store physically-contiguous device-writable descriptors */ 44 struct iovec *in_sg; 45 /* Array to store physically-contiguous device-readable descriptors */ 46 struct iovec *out_sg; 47 } VduseVirtqElement; 48 49 50 /** 51 * vduse_get_virtio_features: 52 * 53 * Get supported virtio features 54 * 55 * Returns: supported feature bits 56 */ 57 uint64_t vduse_get_virtio_features(void); 58 59 /** 60 * vduse_queue_get_dev: 61 * @vq: specified virtqueue 62 * 63 * Get corresponding VDUSE device from the virtqueue. 64 * 65 * Returns: a pointer to VDUSE device on success, NULL on failure. 66 */ 67 VduseDev *vduse_queue_get_dev(VduseVirtq *vq); 68 69 /** 70 * vduse_queue_get_fd: 71 * @vq: specified virtqueue 72 * 73 * Get the kick fd for the virtqueue. 74 * 75 * Returns: file descriptor on success, -1 on failure. 76 */ 77 int vduse_queue_get_fd(VduseVirtq *vq); 78 79 /** 80 * vduse_queue_pop: 81 * @vq: specified virtqueue 82 * @sz: the size of struct to return (must be >= VduseVirtqElement) 83 * 84 * Pop an element from virtqueue available ring. 85 * 86 * Returns: a pointer to a structure containing VduseVirtqElement on success, 87 * NULL on failure. 88 */ 89 void *vduse_queue_pop(VduseVirtq *vq, size_t sz); 90 91 /** 92 * vduse_queue_push: 93 * @vq: specified virtqueue 94 * @elem: pointer to VduseVirtqElement returned by vduse_queue_pop() 95 * @len: length in bytes to write 96 * 97 * Push an element to virtqueue used ring. 98 */ 99 void vduse_queue_push(VduseVirtq *vq, const VduseVirtqElement *elem, 100 unsigned int len); 101 /** 102 * vduse_queue_notify: 103 * @vq: specified virtqueue 104 * 105 * Request to notify the queue. 106 */ 107 void vduse_queue_notify(VduseVirtq *vq); 108 109 /** 110 * vduse_dev_get_priv: 111 * @dev: VDUSE device 112 * 113 * Get the private pointer passed to vduse_dev_create(). 114 * 115 * Returns: private pointer on success, NULL on failure. 116 */ 117 void *vduse_dev_get_priv(VduseDev *dev); 118 119 /** 120 * vduse_dev_get_queue: 121 * @dev: VDUSE device 122 * @index: virtqueue index 123 * 124 * Get the specified virtqueue. 125 * 126 * Returns: a pointer to the virtqueue on success, NULL on failure. 127 */ 128 VduseVirtq *vduse_dev_get_queue(VduseDev *dev, int index); 129 130 /** 131 * vduse_dev_get_fd: 132 * @dev: VDUSE device 133 * 134 * Get the control message fd for the VDUSE device. 135 * 136 * Returns: file descriptor on success, -1 on failure. 137 */ 138 int vduse_dev_get_fd(VduseDev *dev); 139 140 /** 141 * vduse_dev_handler: 142 * @dev: VDUSE device 143 * 144 * Used to process the control message. 145 * 146 * Returns: file descriptor on success, -errno on failure. 147 */ 148 int vduse_dev_handler(VduseDev *dev); 149 150 /** 151 * vduse_dev_update_config: 152 * @dev: VDUSE device 153 * @size: the size to write to configuration space 154 * @offset: the offset from the beginning of configuration space 155 * @buffer: the buffer used to write from 156 * 157 * Update device configuration space and inject a config interrupt. 158 * 159 * Returns: 0 on success, -errno on failure. 160 */ 161 int vduse_dev_update_config(VduseDev *dev, uint32_t size, 162 uint32_t offset, char *buffer); 163 164 /** 165 * vduse_dev_setup_queue: 166 * @dev: VDUSE device 167 * @index: virtqueue index 168 * @max_size: the max size of virtqueue 169 * 170 * Setup the specified virtqueue. 171 * 172 * Returns: 0 on success, -errno on failure. 173 */ 174 int vduse_dev_setup_queue(VduseDev *dev, int index, int max_size); 175 176 /** 177 * vduse_dev_create_by_fd: 178 * @fd: passed file descriptor 179 * @num_queues: the number of virtqueues 180 * @ops: the operation of VDUSE backend 181 * @priv: private pointer 182 * 183 * Create VDUSE device from a passed file descriptor. 184 * 185 * Returns: pointer to VDUSE device on success, NULL on failure. 186 */ 187 VduseDev *vduse_dev_create_by_fd(int fd, uint16_t num_queues, 188 const VduseOps *ops, void *priv); 189 190 /** 191 * vduse_dev_create_by_name: 192 * @name: VDUSE device name 193 * @num_queues: the number of virtqueues 194 * @ops: the operation of VDUSE backend 195 * @priv: private pointer 196 * 197 * Create VDUSE device on /dev/vduse/$NAME. 198 * 199 * Returns: pointer to VDUSE device on success, NULL on failure. 200 */ 201 VduseDev *vduse_dev_create_by_name(const char *name, uint16_t num_queues, 202 const VduseOps *ops, void *priv); 203 204 /** 205 * vduse_dev_create: 206 * @name: VDUSE device name 207 * @device_id: virtio device id 208 * @vendor_id: virtio vendor id 209 * @features: virtio features 210 * @num_queues: the number of virtqueues 211 * @config_size: the size of the configuration space 212 * @config: the buffer of the configuration space 213 * @ops: the operation of VDUSE backend 214 * @priv: private pointer 215 * 216 * Create VDUSE device. 217 * 218 * Returns: pointer to VDUSE device on success, NULL on failure. 219 */ 220 VduseDev *vduse_dev_create(const char *name, uint32_t device_id, 221 uint32_t vendor_id, uint64_t features, 222 uint16_t num_queues, uint32_t config_size, 223 char *config, const VduseOps *ops, void *priv); 224 225 /** 226 * vduse_dev_destroy: 227 * @dev: VDUSE device 228 * 229 * Destroy the VDUSE device. 230 * 231 * Returns: 0 on success, -errno on failure. 232 */ 233 int vduse_dev_destroy(VduseDev *dev); 234 235 #endif 236