13a4d5c94SMichael S. Tsirkin #ifndef _VHOST_H 23a4d5c94SMichael S. Tsirkin #define _VHOST_H 33a4d5c94SMichael S. Tsirkin 43a4d5c94SMichael S. Tsirkin #include <linux/eventfd.h> 53a4d5c94SMichael S. Tsirkin #include <linux/vhost.h> 63a4d5c94SMichael S. Tsirkin #include <linux/mm.h> 73a4d5c94SMichael S. Tsirkin #include <linux/mutex.h> 83a4d5c94SMichael S. Tsirkin #include <linux/poll.h> 93a4d5c94SMichael S. Tsirkin #include <linux/file.h> 103a4d5c94SMichael S. Tsirkin #include <linux/skbuff.h> 113a4d5c94SMichael S. Tsirkin #include <linux/uio.h> 123a4d5c94SMichael S. Tsirkin #include <linux/virtio_config.h> 133a4d5c94SMichael S. Tsirkin #include <linux/virtio_ring.h> 14*60063497SArun Sharma #include <linux/atomic.h> 153a4d5c94SMichael S. Tsirkin 16bab632d6SMichael S. Tsirkin /* This is for zerocopy, used buffer len is set to 1 when lower device DMA 17bab632d6SMichael S. Tsirkin * done */ 18bab632d6SMichael S. Tsirkin #define VHOST_DMA_DONE_LEN 1 19bab632d6SMichael S. Tsirkin #define VHOST_DMA_CLEAR_LEN 0 20bab632d6SMichael S. Tsirkin 213a4d5c94SMichael S. Tsirkin struct vhost_device; 223a4d5c94SMichael S. Tsirkin 23c23f3445STejun Heo struct vhost_work; 24c23f3445STejun Heo typedef void (*vhost_work_fn_t)(struct vhost_work *work); 25c23f3445STejun Heo 26c23f3445STejun Heo struct vhost_work { 27c23f3445STejun Heo struct list_head node; 28c23f3445STejun Heo vhost_work_fn_t fn; 29c23f3445STejun Heo wait_queue_head_t done; 30c23f3445STejun Heo int flushing; 31c23f3445STejun Heo unsigned queue_seq; 32c23f3445STejun Heo unsigned done_seq; 33c23f3445STejun Heo }; 34c23f3445STejun Heo 353a4d5c94SMichael S. Tsirkin /* Poll a file (eventfd or socket) */ 363a4d5c94SMichael S. Tsirkin /* Note: there's nothing vhost specific about this structure. */ 373a4d5c94SMichael S. Tsirkin struct vhost_poll { 383a4d5c94SMichael S. Tsirkin poll_table table; 393a4d5c94SMichael S. Tsirkin wait_queue_head_t *wqh; 403a4d5c94SMichael S. Tsirkin wait_queue_t wait; 41c23f3445STejun Heo struct vhost_work work; 423a4d5c94SMichael S. Tsirkin unsigned long mask; 43c23f3445STejun Heo struct vhost_dev *dev; 443a4d5c94SMichael S. Tsirkin }; 453a4d5c94SMichael S. Tsirkin 46c23f3445STejun Heo void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, 47c23f3445STejun Heo unsigned long mask, struct vhost_dev *dev); 483a4d5c94SMichael S. Tsirkin void vhost_poll_start(struct vhost_poll *poll, struct file *file); 493a4d5c94SMichael S. Tsirkin void vhost_poll_stop(struct vhost_poll *poll); 503a4d5c94SMichael S. Tsirkin void vhost_poll_flush(struct vhost_poll *poll); 513a4d5c94SMichael S. Tsirkin void vhost_poll_queue(struct vhost_poll *poll); 523a4d5c94SMichael S. Tsirkin 533a4d5c94SMichael S. Tsirkin struct vhost_log { 543a4d5c94SMichael S. Tsirkin u64 addr; 553a4d5c94SMichael S. Tsirkin u64 len; 563a4d5c94SMichael S. Tsirkin }; 573a4d5c94SMichael S. Tsirkin 58bab632d6SMichael S. Tsirkin struct vhost_virtqueue; 59bab632d6SMichael S. Tsirkin 60bab632d6SMichael S. Tsirkin struct vhost_ubuf_ref { 61bab632d6SMichael S. Tsirkin struct kref kref; 62bab632d6SMichael S. Tsirkin wait_queue_head_t wait; 63bab632d6SMichael S. Tsirkin struct vhost_virtqueue *vq; 64bab632d6SMichael S. Tsirkin }; 65bab632d6SMichael S. Tsirkin 66bab632d6SMichael S. Tsirkin struct vhost_ubuf_ref *vhost_ubuf_alloc(struct vhost_virtqueue *, bool zcopy); 67bab632d6SMichael S. Tsirkin void vhost_ubuf_put(struct vhost_ubuf_ref *); 68bab632d6SMichael S. Tsirkin void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *); 69bab632d6SMichael S. Tsirkin 703a4d5c94SMichael S. Tsirkin /* The virtqueue structure describes a queue attached to a device. */ 713a4d5c94SMichael S. Tsirkin struct vhost_virtqueue { 723a4d5c94SMichael S. Tsirkin struct vhost_dev *dev; 733a4d5c94SMichael S. Tsirkin 743a4d5c94SMichael S. Tsirkin /* The actual ring of buffers. */ 753a4d5c94SMichael S. Tsirkin struct mutex mutex; 763a4d5c94SMichael S. Tsirkin unsigned int num; 773a4d5c94SMichael S. Tsirkin struct vring_desc __user *desc; 783a4d5c94SMichael S. Tsirkin struct vring_avail __user *avail; 793a4d5c94SMichael S. Tsirkin struct vring_used __user *used; 803a4d5c94SMichael S. Tsirkin struct file *kick; 813a4d5c94SMichael S. Tsirkin struct file *call; 823a4d5c94SMichael S. Tsirkin struct file *error; 833a4d5c94SMichael S. Tsirkin struct eventfd_ctx *call_ctx; 843a4d5c94SMichael S. Tsirkin struct eventfd_ctx *error_ctx; 853a4d5c94SMichael S. Tsirkin struct eventfd_ctx *log_ctx; 863a4d5c94SMichael S. Tsirkin 873a4d5c94SMichael S. Tsirkin struct vhost_poll poll; 883a4d5c94SMichael S. Tsirkin 893a4d5c94SMichael S. Tsirkin /* The routine to call when the Guest pings us, or timeout. */ 90c23f3445STejun Heo vhost_work_fn_t handle_kick; 913a4d5c94SMichael S. Tsirkin 923a4d5c94SMichael S. Tsirkin /* Last available index we saw. */ 933a4d5c94SMichael S. Tsirkin u16 last_avail_idx; 943a4d5c94SMichael S. Tsirkin 953a4d5c94SMichael S. Tsirkin /* Caches available index value from user. */ 963a4d5c94SMichael S. Tsirkin u16 avail_idx; 973a4d5c94SMichael S. Tsirkin 983a4d5c94SMichael S. Tsirkin /* Last index we used. */ 993a4d5c94SMichael S. Tsirkin u16 last_used_idx; 1003a4d5c94SMichael S. Tsirkin 1013a4d5c94SMichael S. Tsirkin /* Used flags */ 1023a4d5c94SMichael S. Tsirkin u16 used_flags; 1033a4d5c94SMichael S. Tsirkin 1048ea8cf89SMichael S. Tsirkin /* Last used index value we have signalled on */ 1058ea8cf89SMichael S. Tsirkin u16 signalled_used; 1068ea8cf89SMichael S. Tsirkin 1078ea8cf89SMichael S. Tsirkin /* Last used index value we have signalled on */ 1088ea8cf89SMichael S. Tsirkin bool signalled_used_valid; 1098ea8cf89SMichael S. Tsirkin 1103a4d5c94SMichael S. Tsirkin /* Log writes to used structure. */ 1113a4d5c94SMichael S. Tsirkin bool log_used; 1123a4d5c94SMichael S. Tsirkin u64 log_addr; 1133a4d5c94SMichael S. Tsirkin 114e0e9b406SJason Wang struct iovec iov[UIO_MAXIOV]; 115e0e9b406SJason Wang /* hdr is used to store the virtio header. 116e0e9b406SJason Wang * Since each iovec has >= 1 byte length, we never need more than 117e0e9b406SJason Wang * header length entries to store the header. */ 118e0e9b406SJason Wang struct iovec hdr[sizeof(struct virtio_net_hdr_mrg_rxbuf)]; 119e0e9b406SJason Wang struct iovec *indirect; 1208dd014adSDavid Stevens size_t vhost_hlen; 1218dd014adSDavid Stevens size_t sock_hlen; 122e0e9b406SJason Wang struct vring_used_elem *heads; 1233a4d5c94SMichael S. Tsirkin /* We use a kind of RCU to access private pointer. 124c23f3445STejun Heo * All readers access it from worker, which makes it possible to 125c23f3445STejun Heo * flush the vhost_work instead of synchronize_rcu. Therefore readers do 1263a4d5c94SMichael S. Tsirkin * not need to call rcu_read_lock/rcu_read_unlock: the beginning of 127c23f3445STejun Heo * vhost_work execution acts instead of rcu_read_lock() and the end of 128a290aec8SJason Wang * vhost_work execution acts instead of rcu_read_unlock(). 1293a4d5c94SMichael S. Tsirkin * Writers use virtqueue mutex. */ 13028457ee6SArnd Bergmann void __rcu *private_data; 1313a4d5c94SMichael S. Tsirkin /* Log write descriptors */ 1323a4d5c94SMichael S. Tsirkin void __user *log_base; 133e0e9b406SJason Wang struct vhost_log *log; 134bab632d6SMichael S. Tsirkin /* vhost zerocopy support fields below: */ 135bab632d6SMichael S. Tsirkin /* last used idx for outstanding DMA zerocopy buffers */ 136bab632d6SMichael S. Tsirkin int upend_idx; 137bab632d6SMichael S. Tsirkin /* first used idx for DMA done zerocopy buffers */ 138bab632d6SMichael S. Tsirkin int done_idx; 139bab632d6SMichael S. Tsirkin /* an array of userspace buffers info */ 140bab632d6SMichael S. Tsirkin struct ubuf_info *ubuf_info; 141bab632d6SMichael S. Tsirkin /* Reference counting for outstanding ubufs. 142bab632d6SMichael S. Tsirkin * Protected by vq mutex. Writers must also take device mutex. */ 143bab632d6SMichael S. Tsirkin struct vhost_ubuf_ref *ubufs; 1443a4d5c94SMichael S. Tsirkin }; 1453a4d5c94SMichael S. Tsirkin 1463a4d5c94SMichael S. Tsirkin struct vhost_dev { 1473a4d5c94SMichael S. Tsirkin /* Readers use RCU to access memory table pointer 1483a4d5c94SMichael S. Tsirkin * log base pointer and features. 1493a4d5c94SMichael S. Tsirkin * Writers use mutex below.*/ 15028457ee6SArnd Bergmann struct vhost_memory __rcu *memory; 1513a4d5c94SMichael S. Tsirkin struct mm_struct *mm; 1523a4d5c94SMichael S. Tsirkin struct mutex mutex; 1533a4d5c94SMichael S. Tsirkin unsigned acked_features; 1543a4d5c94SMichael S. Tsirkin struct vhost_virtqueue *vqs; 1553a4d5c94SMichael S. Tsirkin int nvqs; 1563a4d5c94SMichael S. Tsirkin struct file *log_file; 1573a4d5c94SMichael S. Tsirkin struct eventfd_ctx *log_ctx; 158c23f3445STejun Heo spinlock_t work_lock; 159c23f3445STejun Heo struct list_head work_list; 160c23f3445STejun Heo struct task_struct *worker; 1613a4d5c94SMichael S. Tsirkin }; 1623a4d5c94SMichael S. Tsirkin 1633a4d5c94SMichael S. Tsirkin long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue *vqs, int nvqs); 1643a4d5c94SMichael S. Tsirkin long vhost_dev_check_owner(struct vhost_dev *); 1653a4d5c94SMichael S. Tsirkin long vhost_dev_reset_owner(struct vhost_dev *); 1663a4d5c94SMichael S. Tsirkin void vhost_dev_cleanup(struct vhost_dev *); 1673a4d5c94SMichael S. Tsirkin long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, unsigned long arg); 1683a4d5c94SMichael S. Tsirkin int vhost_vq_access_ok(struct vhost_virtqueue *vq); 1693a4d5c94SMichael S. Tsirkin int vhost_log_access_ok(struct vhost_dev *); 1703a4d5c94SMichael S. Tsirkin 171d5675bd2SMichael S. Tsirkin int vhost_get_vq_desc(struct vhost_dev *, struct vhost_virtqueue *, 1723a4d5c94SMichael S. Tsirkin struct iovec iov[], unsigned int iov_count, 1733a4d5c94SMichael S. Tsirkin unsigned int *out_num, unsigned int *in_num, 1743a4d5c94SMichael S. Tsirkin struct vhost_log *log, unsigned int *log_num); 1758dd014adSDavid Stevens void vhost_discard_vq_desc(struct vhost_virtqueue *, int n); 1763a4d5c94SMichael S. Tsirkin 177f59281daSJason Wang int vhost_init_used(struct vhost_virtqueue *); 1783a4d5c94SMichael S. Tsirkin int vhost_add_used(struct vhost_virtqueue *, unsigned int head, int len); 1798dd014adSDavid Stevens int vhost_add_used_n(struct vhost_virtqueue *, struct vring_used_elem *heads, 1808dd014adSDavid Stevens unsigned count); 1813a4d5c94SMichael S. Tsirkin void vhost_add_used_and_signal(struct vhost_dev *, struct vhost_virtqueue *, 1828dd014adSDavid Stevens unsigned int id, int len); 1838dd014adSDavid Stevens void vhost_add_used_and_signal_n(struct vhost_dev *, struct vhost_virtqueue *, 1848dd014adSDavid Stevens struct vring_used_elem *heads, unsigned count); 1858dd014adSDavid Stevens void vhost_signal(struct vhost_dev *, struct vhost_virtqueue *); 1868ea8cf89SMichael S. Tsirkin void vhost_disable_notify(struct vhost_dev *, struct vhost_virtqueue *); 1878ea8cf89SMichael S. Tsirkin bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *); 1883a4d5c94SMichael S. Tsirkin 1893a4d5c94SMichael S. Tsirkin int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, 1903a4d5c94SMichael S. Tsirkin unsigned int log_num, u64 len); 191bab632d6SMichael S. Tsirkin void vhost_zerocopy_callback(void *arg); 192bab632d6SMichael S. Tsirkin int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq); 1933a4d5c94SMichael S. Tsirkin 1943a4d5c94SMichael S. Tsirkin #define vq_err(vq, fmt, ...) do { \ 1953a4d5c94SMichael S. Tsirkin pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \ 1963a4d5c94SMichael S. Tsirkin if ((vq)->error_ctx) \ 1973a4d5c94SMichael S. Tsirkin eventfd_signal((vq)->error_ctx, 1);\ 1983a4d5c94SMichael S. Tsirkin } while (0) 1993a4d5c94SMichael S. Tsirkin 2003a4d5c94SMichael S. Tsirkin enum { 2018ea8cf89SMichael S. Tsirkin VHOST_FEATURES = (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | 2028ea8cf89SMichael S. Tsirkin (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | 2038ea8cf89SMichael S. Tsirkin (1ULL << VIRTIO_RING_F_EVENT_IDX) | 2048ea8cf89SMichael S. Tsirkin (1ULL << VHOST_F_LOG_ALL) | 2058ea8cf89SMichael S. Tsirkin (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) | 2068ea8cf89SMichael S. Tsirkin (1ULL << VIRTIO_NET_F_MRG_RXBUF), 2073a4d5c94SMichael S. Tsirkin }; 2083a4d5c94SMichael S. Tsirkin 2093a4d5c94SMichael S. Tsirkin static inline int vhost_has_feature(struct vhost_dev *dev, int bit) 2103a4d5c94SMichael S. Tsirkin { 21128457ee6SArnd Bergmann unsigned acked_features; 21228457ee6SArnd Bergmann 2135e18247bSMichael S. Tsirkin /* TODO: check that we are running from vhost_worker or dev mutex is 2145e18247bSMichael S. Tsirkin * held? */ 2155e18247bSMichael S. Tsirkin acked_features = rcu_dereference_index_check(dev->acked_features, 1); 2163a4d5c94SMichael S. Tsirkin return acked_features & (1 << bit); 2173a4d5c94SMichael S. Tsirkin } 2183a4d5c94SMichael S. Tsirkin 219bab632d6SMichael S. Tsirkin void vhost_enable_zcopy(int vq); 220bab632d6SMichael S. Tsirkin 2213a4d5c94SMichael S. Tsirkin #endif 222