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> 14c23f3445STejun Heo #include <asm/atomic.h> 153a4d5c94SMichael S. Tsirkin 163a4d5c94SMichael S. Tsirkin struct vhost_device; 173a4d5c94SMichael S. Tsirkin 18c23f3445STejun Heo struct vhost_work; 19c23f3445STejun Heo typedef void (*vhost_work_fn_t)(struct vhost_work *work); 20c23f3445STejun Heo 21c23f3445STejun Heo struct vhost_work { 22c23f3445STejun Heo struct list_head node; 23c23f3445STejun Heo vhost_work_fn_t fn; 24c23f3445STejun Heo wait_queue_head_t done; 25c23f3445STejun Heo int flushing; 26c23f3445STejun Heo unsigned queue_seq; 27c23f3445STejun Heo unsigned done_seq; 28c23f3445STejun Heo }; 29c23f3445STejun Heo 303a4d5c94SMichael S. Tsirkin /* Poll a file (eventfd or socket) */ 313a4d5c94SMichael S. Tsirkin /* Note: there's nothing vhost specific about this structure. */ 323a4d5c94SMichael S. Tsirkin struct vhost_poll { 333a4d5c94SMichael S. Tsirkin poll_table table; 343a4d5c94SMichael S. Tsirkin wait_queue_head_t *wqh; 353a4d5c94SMichael S. Tsirkin wait_queue_t wait; 36c23f3445STejun Heo struct vhost_work work; 373a4d5c94SMichael S. Tsirkin unsigned long mask; 38c23f3445STejun Heo struct vhost_dev *dev; 393a4d5c94SMichael S. Tsirkin }; 403a4d5c94SMichael S. Tsirkin 41c23f3445STejun Heo void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, 42c23f3445STejun Heo unsigned long mask, struct vhost_dev *dev); 433a4d5c94SMichael S. Tsirkin void vhost_poll_start(struct vhost_poll *poll, struct file *file); 443a4d5c94SMichael S. Tsirkin void vhost_poll_stop(struct vhost_poll *poll); 453a4d5c94SMichael S. Tsirkin void vhost_poll_flush(struct vhost_poll *poll); 463a4d5c94SMichael S. Tsirkin void vhost_poll_queue(struct vhost_poll *poll); 473a4d5c94SMichael S. Tsirkin 483a4d5c94SMichael S. Tsirkin struct vhost_log { 493a4d5c94SMichael S. Tsirkin u64 addr; 503a4d5c94SMichael S. Tsirkin u64 len; 513a4d5c94SMichael S. Tsirkin }; 523a4d5c94SMichael S. Tsirkin 533a4d5c94SMichael S. Tsirkin /* The virtqueue structure describes a queue attached to a device. */ 543a4d5c94SMichael S. Tsirkin struct vhost_virtqueue { 553a4d5c94SMichael S. Tsirkin struct vhost_dev *dev; 563a4d5c94SMichael S. Tsirkin 573a4d5c94SMichael S. Tsirkin /* The actual ring of buffers. */ 583a4d5c94SMichael S. Tsirkin struct mutex mutex; 593a4d5c94SMichael S. Tsirkin unsigned int num; 603a4d5c94SMichael S. Tsirkin struct vring_desc __user *desc; 613a4d5c94SMichael S. Tsirkin struct vring_avail __user *avail; 623a4d5c94SMichael S. Tsirkin struct vring_used __user *used; 633a4d5c94SMichael S. Tsirkin struct file *kick; 643a4d5c94SMichael S. Tsirkin struct file *call; 653a4d5c94SMichael S. Tsirkin struct file *error; 663a4d5c94SMichael S. Tsirkin struct eventfd_ctx *call_ctx; 673a4d5c94SMichael S. Tsirkin struct eventfd_ctx *error_ctx; 683a4d5c94SMichael S. Tsirkin struct eventfd_ctx *log_ctx; 693a4d5c94SMichael S. Tsirkin 703a4d5c94SMichael S. Tsirkin struct vhost_poll poll; 713a4d5c94SMichael S. Tsirkin 723a4d5c94SMichael S. Tsirkin /* The routine to call when the Guest pings us, or timeout. */ 73c23f3445STejun Heo vhost_work_fn_t handle_kick; 743a4d5c94SMichael S. Tsirkin 753a4d5c94SMichael S. Tsirkin /* Last available index we saw. */ 763a4d5c94SMichael S. Tsirkin u16 last_avail_idx; 773a4d5c94SMichael S. Tsirkin 783a4d5c94SMichael S. Tsirkin /* Caches available index value from user. */ 793a4d5c94SMichael S. Tsirkin u16 avail_idx; 803a4d5c94SMichael S. Tsirkin 813a4d5c94SMichael S. Tsirkin /* Last index we used. */ 823a4d5c94SMichael S. Tsirkin u16 last_used_idx; 833a4d5c94SMichael S. Tsirkin 843a4d5c94SMichael S. Tsirkin /* Used flags */ 853a4d5c94SMichael S. Tsirkin u16 used_flags; 863a4d5c94SMichael S. Tsirkin 873a4d5c94SMichael S. Tsirkin /* Log writes to used structure. */ 883a4d5c94SMichael S. Tsirkin bool log_used; 893a4d5c94SMichael S. Tsirkin u64 log_addr; 903a4d5c94SMichael S. Tsirkin 91e0e9b406SJason Wang struct iovec iov[UIO_MAXIOV]; 92e0e9b406SJason Wang /* hdr is used to store the virtio header. 93e0e9b406SJason Wang * Since each iovec has >= 1 byte length, we never need more than 94e0e9b406SJason Wang * header length entries to store the header. */ 95e0e9b406SJason Wang struct iovec hdr[sizeof(struct virtio_net_hdr_mrg_rxbuf)]; 96e0e9b406SJason Wang struct iovec *indirect; 978dd014adSDavid Stevens size_t vhost_hlen; 988dd014adSDavid Stevens size_t sock_hlen; 99e0e9b406SJason Wang struct vring_used_elem *heads; 1003a4d5c94SMichael S. Tsirkin /* We use a kind of RCU to access private pointer. 101c23f3445STejun Heo * All readers access it from worker, which makes it possible to 102c23f3445STejun Heo * flush the vhost_work instead of synchronize_rcu. Therefore readers do 1033a4d5c94SMichael S. Tsirkin * not need to call rcu_read_lock/rcu_read_unlock: the beginning of 104c23f3445STejun Heo * vhost_work execution acts instead of rcu_read_lock() and the end of 105a290aec8SJason Wang * vhost_work execution acts instead of rcu_read_unlock(). 1063a4d5c94SMichael S. Tsirkin * Writers use virtqueue mutex. */ 10728457ee6SArnd Bergmann void __rcu *private_data; 1083a4d5c94SMichael S. Tsirkin /* Log write descriptors */ 1093a4d5c94SMichael S. Tsirkin void __user *log_base; 110e0e9b406SJason Wang struct vhost_log *log; 1113a4d5c94SMichael S. Tsirkin }; 1123a4d5c94SMichael S. Tsirkin 1133a4d5c94SMichael S. Tsirkin struct vhost_dev { 1143a4d5c94SMichael S. Tsirkin /* Readers use RCU to access memory table pointer 1153a4d5c94SMichael S. Tsirkin * log base pointer and features. 1163a4d5c94SMichael S. Tsirkin * Writers use mutex below.*/ 11728457ee6SArnd Bergmann struct vhost_memory __rcu *memory; 1183a4d5c94SMichael S. Tsirkin struct mm_struct *mm; 1193a4d5c94SMichael S. Tsirkin struct mutex mutex; 1203a4d5c94SMichael S. Tsirkin unsigned acked_features; 1213a4d5c94SMichael S. Tsirkin struct vhost_virtqueue *vqs; 1223a4d5c94SMichael S. Tsirkin int nvqs; 1233a4d5c94SMichael S. Tsirkin struct file *log_file; 1243a4d5c94SMichael S. Tsirkin struct eventfd_ctx *log_ctx; 125c23f3445STejun Heo spinlock_t work_lock; 126c23f3445STejun Heo struct list_head work_list; 127c23f3445STejun Heo struct task_struct *worker; 1283a4d5c94SMichael S. Tsirkin }; 1293a4d5c94SMichael S. Tsirkin 1303a4d5c94SMichael S. Tsirkin long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue *vqs, int nvqs); 1313a4d5c94SMichael S. Tsirkin long vhost_dev_check_owner(struct vhost_dev *); 1323a4d5c94SMichael S. Tsirkin long vhost_dev_reset_owner(struct vhost_dev *); 1333a4d5c94SMichael S. Tsirkin void vhost_dev_cleanup(struct vhost_dev *); 1343a4d5c94SMichael S. Tsirkin long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, unsigned long arg); 1353a4d5c94SMichael S. Tsirkin int vhost_vq_access_ok(struct vhost_virtqueue *vq); 1363a4d5c94SMichael S. Tsirkin int vhost_log_access_ok(struct vhost_dev *); 1373a4d5c94SMichael S. Tsirkin 138d5675bd2SMichael S. Tsirkin int vhost_get_vq_desc(struct vhost_dev *, struct vhost_virtqueue *, 1393a4d5c94SMichael S. Tsirkin struct iovec iov[], unsigned int iov_count, 1403a4d5c94SMichael S. Tsirkin unsigned int *out_num, unsigned int *in_num, 1413a4d5c94SMichael S. Tsirkin struct vhost_log *log, unsigned int *log_num); 1428dd014adSDavid Stevens void vhost_discard_vq_desc(struct vhost_virtqueue *, int n); 1433a4d5c94SMichael S. Tsirkin 1443a4d5c94SMichael S. Tsirkin int vhost_add_used(struct vhost_virtqueue *, unsigned int head, int len); 1458dd014adSDavid Stevens int vhost_add_used_n(struct vhost_virtqueue *, struct vring_used_elem *heads, 1468dd014adSDavid Stevens unsigned count); 1473a4d5c94SMichael S. Tsirkin void vhost_add_used_and_signal(struct vhost_dev *, struct vhost_virtqueue *, 1488dd014adSDavid Stevens unsigned int id, int len); 1498dd014adSDavid Stevens void vhost_add_used_and_signal_n(struct vhost_dev *, struct vhost_virtqueue *, 1508dd014adSDavid Stevens struct vring_used_elem *heads, unsigned count); 1518dd014adSDavid Stevens void vhost_signal(struct vhost_dev *, struct vhost_virtqueue *); 1523a4d5c94SMichael S. Tsirkin void vhost_disable_notify(struct vhost_virtqueue *); 1533a4d5c94SMichael S. Tsirkin bool vhost_enable_notify(struct vhost_virtqueue *); 1543a4d5c94SMichael S. Tsirkin 1553a4d5c94SMichael S. Tsirkin int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, 1563a4d5c94SMichael S. Tsirkin unsigned int log_num, u64 len); 1573a4d5c94SMichael S. Tsirkin 1583a4d5c94SMichael S. Tsirkin #define vq_err(vq, fmt, ...) do { \ 1593a4d5c94SMichael S. Tsirkin pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \ 1603a4d5c94SMichael S. Tsirkin if ((vq)->error_ctx) \ 1613a4d5c94SMichael S. Tsirkin eventfd_signal((vq)->error_ctx, 1);\ 1623a4d5c94SMichael S. Tsirkin } while (0) 1633a4d5c94SMichael S. Tsirkin 1643a4d5c94SMichael S. Tsirkin enum { 1653a4d5c94SMichael S. Tsirkin VHOST_FEATURES = (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | 1663a4d5c94SMichael S. Tsirkin (1 << VIRTIO_RING_F_INDIRECT_DESC) | 1673a4d5c94SMichael S. Tsirkin (1 << VHOST_F_LOG_ALL) | 1688dd014adSDavid Stevens (1 << VHOST_NET_F_VIRTIO_NET_HDR) | 1698dd014adSDavid Stevens (1 << VIRTIO_NET_F_MRG_RXBUF), 1703a4d5c94SMichael S. Tsirkin }; 1713a4d5c94SMichael S. Tsirkin 1723a4d5c94SMichael S. Tsirkin static inline int vhost_has_feature(struct vhost_dev *dev, int bit) 1733a4d5c94SMichael S. Tsirkin { 17428457ee6SArnd Bergmann unsigned acked_features; 17528457ee6SArnd Bergmann 176*5e18247bSMichael S. Tsirkin /* TODO: check that we are running from vhost_worker or dev mutex is 177*5e18247bSMichael S. Tsirkin * held? */ 178*5e18247bSMichael S. Tsirkin acked_features = rcu_dereference_index_check(dev->acked_features, 1); 1793a4d5c94SMichael S. Tsirkin return acked_features & (1 << bit); 1803a4d5c94SMichael S. Tsirkin } 1813a4d5c94SMichael S. Tsirkin 1823a4d5c94SMichael S. Tsirkin #endif 183