libvhost-user.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  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 <linux/vhost.h>
  19. #include "standard-headers/linux/virtio_ring.h"
  20. /* Based on qemu/hw/virtio/vhost-user.c */
  21. #define VHOST_USER_F_PROTOCOL_FEATURES 30
  22. #define VHOST_LOG_PAGE 4096
  23. #define VHOST_MAX_NR_VIRTQUEUE 8
  24. #define VIRTQUEUE_MAX_SIZE 1024
  25. #define VHOST_MEMORY_MAX_NREGIONS 8
  26. enum VhostUserProtocolFeature {
  27. VHOST_USER_PROTOCOL_F_MQ = 0,
  28. VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
  29. VHOST_USER_PROTOCOL_F_RARP = 2,
  30. VHOST_USER_PROTOCOL_F_MAX
  31. };
  32. #define VHOST_USER_PROTOCOL_FEATURE_MASK ((1 << VHOST_USER_PROTOCOL_F_MAX) - 1)
  33. typedef enum VhostUserRequest {
  34. VHOST_USER_NONE = 0,
  35. VHOST_USER_GET_FEATURES = 1,
  36. VHOST_USER_SET_FEATURES = 2,
  37. VHOST_USER_SET_OWNER = 3,
  38. VHOST_USER_RESET_OWNER = 4,
  39. VHOST_USER_SET_MEM_TABLE = 5,
  40. VHOST_USER_SET_LOG_BASE = 6,
  41. VHOST_USER_SET_LOG_FD = 7,
  42. VHOST_USER_SET_VRING_NUM = 8,
  43. VHOST_USER_SET_VRING_ADDR = 9,
  44. VHOST_USER_SET_VRING_BASE = 10,
  45. VHOST_USER_GET_VRING_BASE = 11,
  46. VHOST_USER_SET_VRING_KICK = 12,
  47. VHOST_USER_SET_VRING_CALL = 13,
  48. VHOST_USER_SET_VRING_ERR = 14,
  49. VHOST_USER_GET_PROTOCOL_FEATURES = 15,
  50. VHOST_USER_SET_PROTOCOL_FEATURES = 16,
  51. VHOST_USER_GET_QUEUE_NUM = 17,
  52. VHOST_USER_SET_VRING_ENABLE = 18,
  53. VHOST_USER_SEND_RARP = 19,
  54. VHOST_USER_INPUT_GET_CONFIG = 20,
  55. VHOST_USER_MAX
  56. } VhostUserRequest;
  57. typedef struct VhostUserMemoryRegion {
  58. uint64_t guest_phys_addr;
  59. uint64_t memory_size;
  60. uint64_t userspace_addr;
  61. uint64_t mmap_offset;
  62. } VhostUserMemoryRegion;
  63. typedef struct VhostUserMemory {
  64. uint32_t nregions;
  65. uint32_t padding;
  66. VhostUserMemoryRegion regions[VHOST_MEMORY_MAX_NREGIONS];
  67. } VhostUserMemory;
  68. typedef struct VhostUserLog {
  69. uint64_t mmap_size;
  70. uint64_t mmap_offset;
  71. } VhostUserLog;
  72. #if defined(_WIN32)
  73. # define VU_PACKED __attribute__((gcc_struct, packed))
  74. #else
  75. # define VU_PACKED __attribute__((packed))
  76. #endif
  77. typedef struct VhostUserMsg {
  78. VhostUserRequest request;
  79. #define VHOST_USER_VERSION_MASK (0x3)
  80. #define VHOST_USER_REPLY_MASK (0x1 << 2)
  81. uint32_t flags;
  82. uint32_t size; /* the following payload size */
  83. union {
  84. #define VHOST_USER_VRING_IDX_MASK (0xff)
  85. #define VHOST_USER_VRING_NOFD_MASK (0x1 << 8)
  86. uint64_t u64;
  87. struct vhost_vring_state state;
  88. struct vhost_vring_addr addr;
  89. VhostUserMemory memory;
  90. VhostUserLog log;
  91. } payload;
  92. int fds[VHOST_MEMORY_MAX_NREGIONS];
  93. int fd_num;
  94. uint8_t *data;
  95. } VU_PACKED VhostUserMsg;
  96. typedef struct VuDevRegion {
  97. /* Guest Physical address. */
  98. uint64_t gpa;
  99. /* Memory region size. */
  100. uint64_t size;
  101. /* QEMU virtual address (userspace). */
  102. uint64_t qva;
  103. /* Starting offset in our mmaped space. */
  104. uint64_t mmap_offset;
  105. /* Start address of mmaped space. */
  106. uint64_t mmap_addr;
  107. } VuDevRegion;
  108. typedef struct VuDev VuDev;
  109. typedef uint64_t (*vu_get_features_cb) (VuDev *dev);
  110. typedef void (*vu_set_features_cb) (VuDev *dev, uint64_t features);
  111. typedef int (*vu_process_msg_cb) (VuDev *dev, VhostUserMsg *vmsg,
  112. int *do_reply);
  113. typedef void (*vu_queue_set_started_cb) (VuDev *dev, int qidx, bool started);
  114. typedef struct VuDevIface {
  115. /* called by VHOST_USER_GET_FEATURES to get the features bitmask */
  116. vu_get_features_cb get_features;
  117. /* enable vhost implementation features */
  118. vu_set_features_cb set_features;
  119. /* get the protocol feature bitmask from the underlying vhost
  120. * implementation */
  121. vu_get_features_cb get_protocol_features;
  122. /* enable protocol features in the underlying vhost implementation. */
  123. vu_set_features_cb set_protocol_features;
  124. /* process_msg is called for each vhost-user message received */
  125. /* skip libvhost-user processing if return value != 0 */
  126. vu_process_msg_cb process_msg;
  127. /* tells when queues can be processed */
  128. vu_queue_set_started_cb queue_set_started;
  129. } VuDevIface;
  130. typedef void (*vu_queue_handler_cb) (VuDev *dev, int qidx);
  131. typedef struct VuRing {
  132. unsigned int num;
  133. struct vring_desc *desc;
  134. struct vring_avail *avail;
  135. struct vring_used *used;
  136. uint64_t log_guest_addr;
  137. uint32_t flags;
  138. } VuRing;
  139. typedef struct VuVirtq {
  140. VuRing vring;
  141. /* Next head to pop */
  142. uint16_t last_avail_idx;
  143. /* Last avail_idx read from VQ. */
  144. uint16_t shadow_avail_idx;
  145. uint16_t used_idx;
  146. /* Last used index value we have signalled on */
  147. uint16_t signalled_used;
  148. /* Last used index value we have signalled on */
  149. bool signalled_used_valid;
  150. /* Notification enabled? */
  151. bool notification;
  152. int inuse;
  153. vu_queue_handler_cb handler;
  154. int call_fd;
  155. int kick_fd;
  156. int err_fd;
  157. unsigned int enable;
  158. bool started;
  159. } VuVirtq;
  160. enum VuWatchCondtion {
  161. VU_WATCH_IN = 1 << 0,
  162. VU_WATCH_OUT = 1 << 1,
  163. VU_WATCH_PRI = 1 << 2,
  164. VU_WATCH_ERR = 1 << 3,
  165. VU_WATCH_HUP = 1 << 4,
  166. };
  167. typedef void (*vu_panic_cb) (VuDev *dev, const char *err);
  168. typedef void (*vu_watch_cb) (VuDev *dev, int condition, void *data);
  169. typedef void (*vu_set_watch_cb) (VuDev *dev, int fd, int condition,
  170. vu_watch_cb cb, void *data);
  171. typedef void (*vu_remove_watch_cb) (VuDev *dev, int fd);
  172. struct VuDev {
  173. int sock;
  174. uint32_t nregions;
  175. VuDevRegion regions[VHOST_MEMORY_MAX_NREGIONS];
  176. VuVirtq vq[VHOST_MAX_NR_VIRTQUEUE];
  177. int log_call_fd;
  178. uint64_t log_size;
  179. uint8_t *log_table;
  180. uint64_t features;
  181. uint64_t protocol_features;
  182. bool broken;
  183. /* @set_watch: add or update the given fd to the watch set,
  184. * call cb when condition is met */
  185. vu_set_watch_cb set_watch;
  186. /* @remove_watch: remove the given fd from the watch set */
  187. vu_remove_watch_cb remove_watch;
  188. /* @panic: encountered an unrecoverable error, you may try to
  189. * re-initialize */
  190. vu_panic_cb panic;
  191. const VuDevIface *iface;
  192. };
  193. typedef struct VuVirtqElement {
  194. unsigned int index;
  195. unsigned int out_num;
  196. unsigned int in_num;
  197. struct iovec *in_sg;
  198. struct iovec *out_sg;
  199. } VuVirtqElement;
  200. /**
  201. * vu_init:
  202. * @dev: a VuDev context
  203. * @socket: the socket connected to vhost-user master
  204. * @panic: a panic callback
  205. * @set_watch: a set_watch callback
  206. * @remove_watch: a remove_watch callback
  207. * @iface: a VuDevIface structure with vhost-user device callbacks
  208. *
  209. * Intializes a VuDev vhost-user context.
  210. **/
  211. void vu_init(VuDev *dev,
  212. int socket,
  213. vu_panic_cb panic,
  214. vu_set_watch_cb set_watch,
  215. vu_remove_watch_cb remove_watch,
  216. const VuDevIface *iface);
  217. /**
  218. * vu_deinit:
  219. * @dev: a VuDev context
  220. *
  221. * Cleans up the VuDev context
  222. */
  223. void vu_deinit(VuDev *dev);
  224. /**
  225. * vu_dispatch:
  226. * @dev: a VuDev context
  227. *
  228. * Process one vhost-user message.
  229. *
  230. * Returns: TRUE on success, FALSE on failure.
  231. */
  232. bool vu_dispatch(VuDev *dev);
  233. /**
  234. * vu_gpa_to_va:
  235. * @dev: a VuDev context
  236. * @guest_addr: guest address
  237. *
  238. * Translate a guest address to a pointer. Returns NULL on failure.
  239. */
  240. void *vu_gpa_to_va(VuDev *dev, uint64_t guest_addr);
  241. /**
  242. * vu_get_queue:
  243. * @dev: a VuDev context
  244. * @qidx: queue index
  245. *
  246. * Returns the queue number @qidx.
  247. */
  248. VuVirtq *vu_get_queue(VuDev *dev, int qidx);
  249. /**
  250. * vu_set_queue_handler:
  251. * @dev: a VuDev context
  252. * @vq: a VuVirtq queue
  253. * @handler: the queue handler callback
  254. *
  255. * Set the queue handler. This function may be called several times
  256. * for the same queue. If called with NULL @handler, the handler is
  257. * removed.
  258. */
  259. void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
  260. vu_queue_handler_cb handler);
  261. /**
  262. * vu_queue_set_notification:
  263. * @dev: a VuDev context
  264. * @vq: a VuVirtq queue
  265. * @enable: state
  266. *
  267. * Set whether the queue notifies (via event index or interrupt)
  268. */
  269. void vu_queue_set_notification(VuDev *dev, VuVirtq *vq, int enable);
  270. /**
  271. * vu_queue_enabled:
  272. * @dev: a VuDev context
  273. * @vq: a VuVirtq queue
  274. *
  275. * Returns: whether the queue is enabled.
  276. */
  277. bool vu_queue_enabled(VuDev *dev, VuVirtq *vq);
  278. /**
  279. * vu_queue_empty:
  280. * @dev: a VuDev context
  281. * @vq: a VuVirtq queue
  282. *
  283. * Returns: true if the queue is empty or not ready.
  284. */
  285. bool vu_queue_empty(VuDev *dev, VuVirtq *vq);
  286. /**
  287. * vu_queue_notify:
  288. * @dev: a VuDev context
  289. * @vq: a VuVirtq queue
  290. *
  291. * Request to notify the queue via callfd (skipped if unnecessary)
  292. */
  293. void vu_queue_notify(VuDev *dev, VuVirtq *vq);
  294. /**
  295. * vu_queue_pop:
  296. * @dev: a VuDev context
  297. * @vq: a VuVirtq queue
  298. * @sz: the size of struct to return (must be >= VuVirtqElement)
  299. *
  300. * Returns: a VuVirtqElement filled from the queue or NULL.
  301. */
  302. void *vu_queue_pop(VuDev *dev, VuVirtq *vq, size_t sz);
  303. /**
  304. * vu_queue_rewind:
  305. * @dev: a VuDev context
  306. * @vq: a VuVirtq queue
  307. * @num: number of elements to push back
  308. *
  309. * Pretend that elements weren't popped from the virtqueue. The next
  310. * virtqueue_pop() will refetch the oldest element.
  311. *
  312. * Returns: true on success, false if @num is greater than the number of in use
  313. * elements.
  314. */
  315. bool vu_queue_rewind(VuDev *dev, VuVirtq *vq, unsigned int num);
  316. /**
  317. * vu_queue_fill:
  318. * @dev: a VuDev context
  319. * @vq: a VuVirtq queue
  320. * @elem: a VuVirtqElement
  321. * @len: length in bytes to write
  322. * @idx: optional offset for the used ring index (0 in general)
  323. *
  324. * Fill the used ring with @elem element.
  325. */
  326. void vu_queue_fill(VuDev *dev, VuVirtq *vq,
  327. const VuVirtqElement *elem,
  328. unsigned int len, unsigned int idx);
  329. /**
  330. * vu_queue_push:
  331. * @dev: a VuDev context
  332. * @vq: a VuVirtq queue
  333. * @elem: a VuVirtqElement
  334. * @len: length in bytes to write
  335. *
  336. * Helper that combines vu_queue_fill() with a vu_queue_flush().
  337. */
  338. void vu_queue_push(VuDev *dev, VuVirtq *vq,
  339. const VuVirtqElement *elem, unsigned int len);
  340. /**
  341. * vu_queue_flush:
  342. * @dev: a VuDev context
  343. * @vq: a VuVirtq queue
  344. * @num: number of elements to flush
  345. *
  346. * Mark the last number of elements as done (used.idx is updated by
  347. * num elements).
  348. */
  349. void vu_queue_flush(VuDev *dev, VuVirtq *vq, unsigned int num);
  350. /**
  351. * vu_queue_get_avail_bytes:
  352. * @dev: a VuDev context
  353. * @vq: a VuVirtq queue
  354. * @in_bytes: in bytes
  355. * @out_bytes: out bytes
  356. * @max_in_bytes: stop counting after max_in_bytes
  357. * @max_out_bytes: stop counting after max_out_bytes
  358. *
  359. * Count the number of available bytes, up to max_in_bytes/max_out_bytes.
  360. */
  361. void vu_queue_get_avail_bytes(VuDev *vdev, VuVirtq *vq, unsigned int *in_bytes,
  362. unsigned int *out_bytes,
  363. unsigned max_in_bytes, unsigned max_out_bytes);
  364. /**
  365. * vu_queue_avail_bytes:
  366. * @dev: a VuDev context
  367. * @vq: a VuVirtq queue
  368. * @in_bytes: expected in bytes
  369. * @out_bytes: expected out bytes
  370. *
  371. * Returns: true if in_bytes <= in_total && out_bytes <= out_total
  372. */
  373. bool vu_queue_avail_bytes(VuDev *dev, VuVirtq *vq, unsigned int in_bytes,
  374. unsigned int out_bytes);
  375. #endif /* LIBVHOST_USER_H */