libvhost-user.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. /*
  2. * Vhost User library
  3. *
  4. * Copyright (c) 2016 Red Hat, Inc.
  5. *
  6. * Authors:
  7. * Victor Kaplansky <victork@redhat.com>
  8. * Marc-André Lureau <mlureau@redhat.com>
  9. *
  10. * This work is licensed under the terms of the GNU GPL, version 2 or
  11. * later. See the COPYING file in the top-level directory.
  12. */
  13. #ifndef LIBVHOST_USER_H
  14. #define LIBVHOST_USER_H
  15. #include <stdint.h>
  16. #include <stdbool.h>
  17. #include <stddef.h>
  18. #include <poll.h>
  19. #include <linux/vhost.h>
  20. #include <pthread.h>
  21. #include "standard-headers/linux/virtio_ring.h"
  22. /* Based on qemu/hw/virtio/vhost-user.c */
  23. #define VHOST_USER_F_PROTOCOL_FEATURES 30
  24. #define VHOST_LOG_PAGE 4096
  25. #define VIRTQUEUE_MAX_SIZE 1024
  26. #define VHOST_MEMORY_BASELINE_NREGIONS 8
  27. /*
  28. * vhost in the kernel usually supports 509 mem slots. 509 used to be the
  29. * KVM limit, it supported 512, but 3 were used for internal purposes. This
  30. * limit is sufficient to support many DIMMs and virtio-mem in
  31. * "dynamic-memslots" mode.
  32. */
  33. #define VHOST_USER_MAX_RAM_SLOTS 509
  34. #define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
  35. typedef enum VhostSetConfigType {
  36. VHOST_SET_CONFIG_TYPE_FRONTEND = 0,
  37. VHOST_SET_CONFIG_TYPE_MIGRATION = 1,
  38. } VhostSetConfigType;
  39. /*
  40. * Maximum size of virtio device config space
  41. */
  42. #define VHOST_USER_MAX_CONFIG_SIZE 256
  43. enum VhostUserProtocolFeature {
  44. VHOST_USER_PROTOCOL_F_MQ = 0,
  45. VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
  46. VHOST_USER_PROTOCOL_F_RARP = 2,
  47. VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
  48. VHOST_USER_PROTOCOL_F_NET_MTU = 4,
  49. VHOST_USER_PROTOCOL_F_BACKEND_REQ = 5,
  50. VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
  51. VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
  52. VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
  53. VHOST_USER_PROTOCOL_F_CONFIG = 9,
  54. VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD = 10,
  55. VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
  56. VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
  57. VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS = 14,
  58. VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
  59. /* Feature 16 is reserved for VHOST_USER_PROTOCOL_F_STATUS. */
  60. /* Feature 17 reserved for VHOST_USER_PROTOCOL_F_XEN_MMAP. */
  61. VHOST_USER_PROTOCOL_F_SHARED_OBJECT = 18,
  62. VHOST_USER_PROTOCOL_F_MAX
  63. };
  64. #define VHOST_USER_PROTOCOL_FEATURE_MASK ((1 << VHOST_USER_PROTOCOL_F_MAX) - 1)
  65. typedef enum VhostUserRequest {
  66. VHOST_USER_NONE = 0,
  67. VHOST_USER_GET_FEATURES = 1,
  68. VHOST_USER_SET_FEATURES = 2,
  69. VHOST_USER_SET_OWNER = 3,
  70. VHOST_USER_RESET_OWNER = 4,
  71. VHOST_USER_SET_MEM_TABLE = 5,
  72. VHOST_USER_SET_LOG_BASE = 6,
  73. VHOST_USER_SET_LOG_FD = 7,
  74. VHOST_USER_SET_VRING_NUM = 8,
  75. VHOST_USER_SET_VRING_ADDR = 9,
  76. VHOST_USER_SET_VRING_BASE = 10,
  77. VHOST_USER_GET_VRING_BASE = 11,
  78. VHOST_USER_SET_VRING_KICK = 12,
  79. VHOST_USER_SET_VRING_CALL = 13,
  80. VHOST_USER_SET_VRING_ERR = 14,
  81. VHOST_USER_GET_PROTOCOL_FEATURES = 15,
  82. VHOST_USER_SET_PROTOCOL_FEATURES = 16,
  83. VHOST_USER_GET_QUEUE_NUM = 17,
  84. VHOST_USER_SET_VRING_ENABLE = 18,
  85. VHOST_USER_SEND_RARP = 19,
  86. VHOST_USER_NET_SET_MTU = 20,
  87. VHOST_USER_SET_BACKEND_REQ_FD = 21,
  88. VHOST_USER_IOTLB_MSG = 22,
  89. VHOST_USER_SET_VRING_ENDIAN = 23,
  90. VHOST_USER_GET_CONFIG = 24,
  91. VHOST_USER_SET_CONFIG = 25,
  92. VHOST_USER_CREATE_CRYPTO_SESSION = 26,
  93. VHOST_USER_CLOSE_CRYPTO_SESSION = 27,
  94. VHOST_USER_POSTCOPY_ADVISE = 28,
  95. VHOST_USER_POSTCOPY_LISTEN = 29,
  96. VHOST_USER_POSTCOPY_END = 30,
  97. VHOST_USER_GET_INFLIGHT_FD = 31,
  98. VHOST_USER_SET_INFLIGHT_FD = 32,
  99. VHOST_USER_GPU_SET_SOCKET = 33,
  100. VHOST_USER_VRING_KICK = 35,
  101. VHOST_USER_GET_MAX_MEM_SLOTS = 36,
  102. VHOST_USER_ADD_MEM_REG = 37,
  103. VHOST_USER_REM_MEM_REG = 38,
  104. VHOST_USER_GET_SHARED_OBJECT = 41,
  105. VHOST_USER_MAX
  106. } VhostUserRequest;
  107. typedef enum VhostUserBackendRequest {
  108. VHOST_USER_BACKEND_NONE = 0,
  109. VHOST_USER_BACKEND_IOTLB_MSG = 1,
  110. VHOST_USER_BACKEND_CONFIG_CHANGE_MSG = 2,
  111. VHOST_USER_BACKEND_VRING_HOST_NOTIFIER_MSG = 3,
  112. VHOST_USER_BACKEND_VRING_CALL = 4,
  113. VHOST_USER_BACKEND_VRING_ERR = 5,
  114. VHOST_USER_BACKEND_SHARED_OBJECT_ADD = 6,
  115. VHOST_USER_BACKEND_SHARED_OBJECT_REMOVE = 7,
  116. VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP = 8,
  117. VHOST_USER_BACKEND_MAX
  118. } VhostUserBackendRequest;
  119. typedef struct VhostUserMemoryRegion {
  120. uint64_t guest_phys_addr;
  121. uint64_t memory_size;
  122. uint64_t userspace_addr;
  123. uint64_t mmap_offset;
  124. } VhostUserMemoryRegion;
  125. #define VHOST_USER_MEM_REG_SIZE (sizeof(VhostUserMemoryRegion))
  126. typedef struct VhostUserMemory {
  127. uint32_t nregions;
  128. uint32_t padding;
  129. VhostUserMemoryRegion regions[VHOST_MEMORY_BASELINE_NREGIONS];
  130. } VhostUserMemory;
  131. typedef struct VhostUserMemRegMsg {
  132. uint64_t padding;
  133. VhostUserMemoryRegion region;
  134. } VhostUserMemRegMsg;
  135. typedef struct VhostUserLog {
  136. uint64_t mmap_size;
  137. uint64_t mmap_offset;
  138. } VhostUserLog;
  139. typedef struct VhostUserConfig {
  140. uint32_t offset;
  141. uint32_t size;
  142. uint32_t flags;
  143. uint8_t region[VHOST_USER_MAX_CONFIG_SIZE];
  144. } VhostUserConfig;
  145. static VhostUserConfig c __attribute__ ((unused));
  146. #define VHOST_USER_CONFIG_HDR_SIZE (sizeof(c.offset) \
  147. + sizeof(c.size) \
  148. + sizeof(c.flags))
  149. typedef struct VhostUserVringArea {
  150. uint64_t u64;
  151. uint64_t size;
  152. uint64_t offset;
  153. } VhostUserVringArea;
  154. typedef struct VhostUserInflight {
  155. uint64_t mmap_size;
  156. uint64_t mmap_offset;
  157. uint16_t num_queues;
  158. uint16_t queue_size;
  159. } VhostUserInflight;
  160. #define UUID_LEN 16
  161. typedef struct VhostUserShared {
  162. unsigned char uuid[UUID_LEN];
  163. } VhostUserShared;
  164. #define VU_PACKED __attribute__((packed))
  165. typedef struct VhostUserMsg {
  166. int request;
  167. #define VHOST_USER_VERSION_MASK (0x3)
  168. #define VHOST_USER_REPLY_MASK (0x1 << 2)
  169. #define VHOST_USER_NEED_REPLY_MASK (0x1 << 3)
  170. uint32_t flags;
  171. uint32_t size; /* the following payload size */
  172. union {
  173. #define VHOST_USER_VRING_IDX_MASK (0xff)
  174. #define VHOST_USER_VRING_NOFD_MASK (0x1 << 8)
  175. uint64_t u64;
  176. struct vhost_vring_state state;
  177. struct vhost_vring_addr addr;
  178. VhostUserMemory memory;
  179. VhostUserMemRegMsg memreg;
  180. VhostUserLog log;
  181. VhostUserConfig config;
  182. VhostUserVringArea area;
  183. VhostUserInflight inflight;
  184. VhostUserShared object;
  185. } payload;
  186. int fds[VHOST_MEMORY_BASELINE_NREGIONS];
  187. int fd_num;
  188. uint8_t *data;
  189. } VU_PACKED VhostUserMsg;
  190. typedef struct VuDevRegion {
  191. /* Guest Physical address. */
  192. uint64_t gpa;
  193. /* Memory region size. */
  194. uint64_t size;
  195. /* QEMU virtual address (userspace). */
  196. uint64_t qva;
  197. /* Starting offset in our mmaped space. */
  198. uint64_t mmap_offset;
  199. /* Start address of mmaped space. */
  200. uint64_t mmap_addr;
  201. } VuDevRegion;
  202. typedef struct VuDev VuDev;
  203. typedef uint64_t (*vu_get_features_cb) (VuDev *dev);
  204. typedef void (*vu_set_features_cb) (VuDev *dev, uint64_t features);
  205. typedef int (*vu_process_msg_cb) (VuDev *dev, VhostUserMsg *vmsg,
  206. int *do_reply);
  207. typedef bool (*vu_read_msg_cb) (VuDev *dev, int sock, VhostUserMsg *vmsg);
  208. typedef void (*vu_queue_set_started_cb) (VuDev *dev, int qidx, bool started);
  209. typedef bool (*vu_queue_is_processed_in_order_cb) (VuDev *dev, int qidx);
  210. typedef int (*vu_get_config_cb) (VuDev *dev, uint8_t *config, uint32_t len);
  211. typedef int (*vu_set_config_cb) (VuDev *dev, const uint8_t *data,
  212. uint32_t offset, uint32_t size,
  213. uint32_t flags);
  214. typedef int (*vu_get_shared_object_cb) (VuDev *dev, const unsigned char *uuid);
  215. typedef struct VuDevIface {
  216. /* called by VHOST_USER_GET_FEATURES to get the features bitmask */
  217. vu_get_features_cb get_features;
  218. /* enable vhost implementation features */
  219. vu_set_features_cb set_features;
  220. /* get the protocol feature bitmask from the underlying vhost
  221. * implementation */
  222. vu_get_features_cb get_protocol_features;
  223. /* enable protocol features in the underlying vhost implementation. */
  224. vu_set_features_cb set_protocol_features;
  225. /* process_msg is called for each vhost-user message received */
  226. /* skip libvhost-user processing if return value != 0 */
  227. vu_process_msg_cb process_msg;
  228. /* tells when queues can be processed */
  229. vu_queue_set_started_cb queue_set_started;
  230. /*
  231. * If the queue is processed in order, in which case it will be
  232. * resumed to vring.used->idx. This can help to support resuming
  233. * on unmanaged exit/crash.
  234. */
  235. vu_queue_is_processed_in_order_cb queue_is_processed_in_order;
  236. /* get the config space of the device */
  237. vu_get_config_cb get_config;
  238. /* set the config space of the device */
  239. vu_set_config_cb set_config;
  240. /* get virtio shared object from the underlying vhost implementation. */
  241. vu_get_shared_object_cb get_shared_object;
  242. } VuDevIface;
  243. typedef void (*vu_queue_handler_cb) (VuDev *dev, int qidx);
  244. typedef struct VuRing {
  245. unsigned int num;
  246. struct vring_desc *desc;
  247. struct vring_avail *avail;
  248. struct vring_used *used;
  249. uint64_t log_guest_addr;
  250. uint32_t flags;
  251. } VuRing;
  252. typedef struct VuDescStateSplit {
  253. /* Indicate whether this descriptor is inflight or not.
  254. * Only available for head-descriptor. */
  255. uint8_t inflight;
  256. /* Padding */
  257. uint8_t padding[5];
  258. /* Maintain a list for the last batch of used descriptors.
  259. * Only available when batching is used for submitting */
  260. uint16_t next;
  261. /* Used to preserve the order of fetching available descriptors.
  262. * Only available for head-descriptor. */
  263. uint64_t counter;
  264. } VuDescStateSplit;
  265. typedef struct VuVirtqInflight {
  266. /* The feature flags of this region. Now it's initialized to 0. */
  267. uint64_t features;
  268. /* The version of this region. It's 1 currently.
  269. * Zero value indicates a vm reset happened. */
  270. uint16_t version;
  271. /*
  272. * The size of VuDescStateSplit array. It's equal to the virtqueue size.
  273. * Backend could get it from queue size field of VhostUserInflight.
  274. */
  275. uint16_t desc_num;
  276. /* The head of list that track the last batch of used descriptors. */
  277. uint16_t last_batch_head;
  278. /* Storing the idx value of used ring */
  279. uint16_t used_idx;
  280. /* Used to track the state of each descriptor in descriptor table */
  281. VuDescStateSplit desc[];
  282. } VuVirtqInflight;
  283. typedef struct VuVirtqInflightDesc {
  284. uint16_t index;
  285. uint64_t counter;
  286. } VuVirtqInflightDesc;
  287. typedef struct VuVirtq {
  288. VuRing vring;
  289. VuVirtqInflight *inflight;
  290. VuVirtqInflightDesc *resubmit_list;
  291. uint16_t resubmit_num;
  292. uint64_t counter;
  293. /* Next head to pop */
  294. uint16_t last_avail_idx;
  295. /* Last avail_idx read from VQ. */
  296. uint16_t shadow_avail_idx;
  297. uint16_t used_idx;
  298. /* Last used index value we have signalled on */
  299. uint16_t signalled_used;
  300. /* Last used index value we have signalled on */
  301. bool signalled_used_valid;
  302. /* Notification enabled? */
  303. bool notification;
  304. unsigned int inuse;
  305. vu_queue_handler_cb handler;
  306. int call_fd;
  307. int kick_fd;
  308. int err_fd;
  309. unsigned int enable;
  310. bool started;
  311. /* Guest addresses of our ring */
  312. struct vhost_vring_addr vra;
  313. } VuVirtq;
  314. enum VuWatchCondtion {
  315. VU_WATCH_IN = POLLIN,
  316. VU_WATCH_OUT = POLLOUT,
  317. VU_WATCH_PRI = POLLPRI,
  318. VU_WATCH_ERR = POLLERR,
  319. VU_WATCH_HUP = POLLHUP,
  320. };
  321. typedef void (*vu_panic_cb) (VuDev *dev, const char *err);
  322. typedef void (*vu_watch_cb) (VuDev *dev, int condition, void *data);
  323. typedef void (*vu_set_watch_cb) (VuDev *dev, int fd, int condition,
  324. vu_watch_cb cb, void *data);
  325. typedef void (*vu_remove_watch_cb) (VuDev *dev, int fd);
  326. typedef struct VuDevInflightInfo {
  327. int fd;
  328. void *addr;
  329. uint64_t size;
  330. } VuDevInflightInfo;
  331. struct VuDev {
  332. int sock;
  333. uint32_t nregions;
  334. VuDevRegion *regions;
  335. VuVirtq *vq;
  336. VuDevInflightInfo inflight_info;
  337. int log_call_fd;
  338. /* Must be held while using backend_fd */
  339. pthread_mutex_t backend_mutex;
  340. int backend_fd;
  341. uint64_t log_size;
  342. uint8_t *log_table;
  343. uint64_t features;
  344. uint64_t protocol_features;
  345. bool broken;
  346. uint16_t max_queues;
  347. /*
  348. * @read_msg: custom method to read vhost-user message
  349. *
  350. * Read data from vhost_user socket fd and fill up
  351. * the passed VhostUserMsg *vmsg struct.
  352. *
  353. * If reading fails, it should close the received set of file
  354. * descriptors as socket message's auxiliary data.
  355. *
  356. * For the details, please refer to vu_message_read in libvhost-user.c
  357. * which will be used by default if not custom method is provided when
  358. * calling vu_init
  359. *
  360. * Returns: true if vhost-user message successfully received,
  361. * otherwise return false.
  362. *
  363. */
  364. vu_read_msg_cb read_msg;
  365. /*
  366. * @set_watch: add or update the given fd to the watch set,
  367. * call cb when condition is met.
  368. */
  369. vu_set_watch_cb set_watch;
  370. /* @remove_watch: remove the given fd from the watch set */
  371. vu_remove_watch_cb remove_watch;
  372. /*
  373. * @panic: encountered an unrecoverable error, you may try to re-initialize
  374. */
  375. vu_panic_cb panic;
  376. const VuDevIface *iface;
  377. /* Postcopy data */
  378. int postcopy_ufd;
  379. bool postcopy_listening;
  380. };
  381. typedef struct VuVirtqElement {
  382. unsigned int index;
  383. unsigned int out_num;
  384. unsigned int in_num;
  385. struct iovec *in_sg;
  386. struct iovec *out_sg;
  387. } VuVirtqElement;
  388. /**
  389. * vu_init:
  390. * @dev: a VuDev context
  391. * @max_queues: maximum number of virtqueues
  392. * @socket: the socket connected to vhost-user frontend
  393. * @panic: a panic callback
  394. * @set_watch: a set_watch callback
  395. * @remove_watch: a remove_watch callback
  396. * @iface: a VuDevIface structure with vhost-user device callbacks
  397. *
  398. * Initializes a VuDev vhost-user context.
  399. *
  400. * Returns: true on success, false on failure.
  401. **/
  402. bool vu_init(VuDev *dev,
  403. uint16_t max_queues,
  404. int socket,
  405. vu_panic_cb panic,
  406. vu_read_msg_cb read_msg,
  407. vu_set_watch_cb set_watch,
  408. vu_remove_watch_cb remove_watch,
  409. const VuDevIface *iface);
  410. /**
  411. * vu_deinit:
  412. * @dev: a VuDev context
  413. *
  414. * Cleans up the VuDev context
  415. */
  416. void vu_deinit(VuDev *dev);
  417. /**
  418. * vu_request_to_string: return string for vhost message request
  419. * @req: VhostUserMsg request
  420. *
  421. * Returns a const string, do not free.
  422. */
  423. const char *vu_request_to_string(unsigned int req);
  424. /**
  425. * vu_dispatch:
  426. * @dev: a VuDev context
  427. *
  428. * Process one vhost-user message.
  429. *
  430. * Returns: TRUE on success, FALSE on failure.
  431. */
  432. bool vu_dispatch(VuDev *dev);
  433. /**
  434. * vu_gpa_to_va:
  435. * @dev: a VuDev context
  436. * @plen: guest memory size
  437. * @guest_addr: guest address
  438. *
  439. * Translate a guest address to a pointer. Returns NULL on failure.
  440. */
  441. void *vu_gpa_to_va(VuDev *dev, uint64_t *plen, uint64_t guest_addr);
  442. /**
  443. * vu_get_queue:
  444. * @dev: a VuDev context
  445. * @qidx: queue index
  446. *
  447. * Returns the queue number @qidx.
  448. */
  449. VuVirtq *vu_get_queue(VuDev *dev, int qidx);
  450. /**
  451. * vu_set_queue_handler:
  452. * @dev: a VuDev context
  453. * @vq: a VuVirtq queue
  454. * @handler: the queue handler callback
  455. *
  456. * Set the queue handler. This function may be called several times
  457. * for the same queue. If called with NULL @handler, the handler is
  458. * removed.
  459. */
  460. void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
  461. vu_queue_handler_cb handler);
  462. /**
  463. * vu_set_queue_host_notifier:
  464. * @dev: a VuDev context
  465. * @vq: a VuVirtq queue
  466. * @fd: a file descriptor
  467. * @size: host page size
  468. * @offset: notifier offset in @fd file
  469. *
  470. * Set queue's host notifier. This function may be called several
  471. * times for the same queue. If called with -1 @fd, the notifier
  472. * is removed.
  473. */
  474. bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
  475. int size, int offset);
  476. /**
  477. * vu_lookup_shared_object:
  478. * @dev: a VuDev context
  479. * @uuid: UUID of the shared object
  480. * @dmabuf_fd: output dma-buf file descriptor
  481. *
  482. * Lookup for a virtio shared object (i.e., dma-buf fd) associated with the
  483. * received UUID. Result, if found, is stored in the dmabuf_fd argument.
  484. *
  485. * Returns: whether the virtio object was found.
  486. */
  487. bool vu_lookup_shared_object(VuDev *dev, unsigned char uuid[UUID_LEN],
  488. int *dmabuf_fd);
  489. /**
  490. * vu_add_shared_object:
  491. * @dev: a VuDev context
  492. * @uuid: UUID of the shared object
  493. *
  494. * Registers this back-end as the exporter for the object associated with
  495. * the received UUID.
  496. *
  497. * Returns: TRUE on success, FALSE on failure.
  498. */
  499. bool vu_add_shared_object(VuDev *dev, unsigned char uuid[UUID_LEN]);
  500. /**
  501. * vu_rm_shared_object:
  502. * @dev: a VuDev context
  503. * @uuid: UUID of the shared object
  504. *
  505. * Removes a shared object entry (i.e., back-end entry) associated with the
  506. * received UUID key from the hash table.
  507. *
  508. * Returns: TRUE on success, FALSE on failure.
  509. */
  510. bool vu_rm_shared_object(VuDev *dev, unsigned char uuid[UUID_LEN]);
  511. /**
  512. * vu_queue_set_notification:
  513. * @dev: a VuDev context
  514. * @vq: a VuVirtq queue
  515. * @enable: state
  516. *
  517. * Set whether the queue notifies (via event index or interrupt)
  518. */
  519. void vu_queue_set_notification(VuDev *dev, VuVirtq *vq, int enable);
  520. /**
  521. * vu_queue_enabled:
  522. * @dev: a VuDev context
  523. * @vq: a VuVirtq queue
  524. *
  525. * Returns: whether the queue is enabled.
  526. */
  527. bool vu_queue_enabled(VuDev *dev, VuVirtq *vq);
  528. /**
  529. * vu_queue_started:
  530. * @dev: a VuDev context
  531. * @vq: a VuVirtq queue
  532. *
  533. * Returns: whether the queue is started.
  534. */
  535. bool vu_queue_started(const VuDev *dev, const VuVirtq *vq);
  536. /**
  537. * vu_queue_empty:
  538. * @dev: a VuDev context
  539. * @vq: a VuVirtq queue
  540. *
  541. * Returns: true if the queue is empty or not ready.
  542. */
  543. bool vu_queue_empty(VuDev *dev, VuVirtq *vq);
  544. /**
  545. * vu_queue_notify:
  546. * @dev: a VuDev context
  547. * @vq: a VuVirtq queue
  548. *
  549. * Request to notify the queue via callfd (skipped if unnecessary)
  550. */
  551. void vu_queue_notify(VuDev *dev, VuVirtq *vq);
  552. void vu_config_change_msg(VuDev *dev);
  553. /**
  554. * vu_queue_notify_sync:
  555. * @dev: a VuDev context
  556. * @vq: a VuVirtq queue
  557. *
  558. * Request to notify the queue via callfd (skipped if unnecessary)
  559. * or sync message if possible.
  560. */
  561. void vu_queue_notify_sync(VuDev *dev, VuVirtq *vq);
  562. /**
  563. * vu_queue_pop:
  564. * @dev: a VuDev context
  565. * @vq: a VuVirtq queue
  566. * @sz: the size of struct to return (must be >= VuVirtqElement)
  567. *
  568. * Returns: a VuVirtqElement filled from the queue or NULL. The
  569. * returned element must be free()-d by the caller.
  570. */
  571. void *vu_queue_pop(VuDev *dev, VuVirtq *vq, size_t sz);
  572. /**
  573. * vu_queue_unpop:
  574. * @dev: a VuDev context
  575. * @vq: a VuVirtq queue
  576. * @elem: The #VuVirtqElement
  577. * @len: number of bytes written
  578. *
  579. * Pretend the most recent element wasn't popped from the virtqueue. The next
  580. * call to vu_queue_pop() will refetch the element.
  581. */
  582. void vu_queue_unpop(VuDev *dev, VuVirtq *vq, VuVirtqElement *elem,
  583. size_t len);
  584. /**
  585. * vu_queue_rewind:
  586. * @dev: a VuDev context
  587. * @vq: a VuVirtq queue
  588. * @num: number of elements to push back
  589. *
  590. * Pretend that elements weren't popped from the virtqueue. The next
  591. * virtqueue_pop() will refetch the oldest element.
  592. *
  593. * Returns: true on success, false if @num is greater than the number of in use
  594. * elements.
  595. */
  596. bool vu_queue_rewind(VuDev *dev, VuVirtq *vq, unsigned int num);
  597. /**
  598. * vu_queue_fill:
  599. * @dev: a VuDev context
  600. * @vq: a VuVirtq queue
  601. * @elem: a VuVirtqElement
  602. * @len: length in bytes to write
  603. * @idx: optional offset for the used ring index (0 in general)
  604. *
  605. * Fill the used ring with @elem element.
  606. */
  607. void vu_queue_fill(VuDev *dev, VuVirtq *vq,
  608. const VuVirtqElement *elem,
  609. unsigned int len, unsigned int idx);
  610. /**
  611. * vu_queue_push:
  612. * @dev: a VuDev context
  613. * @vq: a VuVirtq queue
  614. * @elem: a VuVirtqElement
  615. * @len: length in bytes to write
  616. *
  617. * Helper that combines vu_queue_fill() with a vu_queue_flush().
  618. */
  619. void vu_queue_push(VuDev *dev, VuVirtq *vq,
  620. const VuVirtqElement *elem, unsigned int len);
  621. /**
  622. * vu_queue_flush:
  623. * @dev: a VuDev context
  624. * @vq: a VuVirtq queue
  625. * @num: number of elements to flush
  626. *
  627. * Mark the last number of elements as done (used.idx is updated by
  628. * num elements).
  629. */
  630. void vu_queue_flush(VuDev *dev, VuVirtq *vq, unsigned int num);
  631. /**
  632. * vu_queue_get_avail_bytes:
  633. * @dev: a VuDev context
  634. * @vq: a VuVirtq queue
  635. * @in_bytes: in bytes
  636. * @out_bytes: out bytes
  637. * @max_in_bytes: stop counting after max_in_bytes
  638. * @max_out_bytes: stop counting after max_out_bytes
  639. *
  640. * Count the number of available bytes, up to max_in_bytes/max_out_bytes.
  641. */
  642. void vu_queue_get_avail_bytes(VuDev *vdev, VuVirtq *vq, unsigned int *in_bytes,
  643. unsigned int *out_bytes,
  644. unsigned max_in_bytes, unsigned max_out_bytes);
  645. /**
  646. * vu_queue_avail_bytes:
  647. * @dev: a VuDev context
  648. * @vq: a VuVirtq queue
  649. * @in_bytes: expected in bytes
  650. * @out_bytes: expected out bytes
  651. *
  652. * Returns: true if in_bytes <= in_total && out_bytes <= out_total
  653. */
  654. bool vu_queue_avail_bytes(VuDev *dev, VuVirtq *vq, unsigned int in_bytes,
  655. unsigned int out_bytes);
  656. #endif /* LIBVHOST_USER_H */