123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /* SPDX-License-Identifier: (MIT OR GPL-2.0) */
- #ifndef _LINUX_VIRTIO_VDMABUF_H
- #define _LINUX_VIRTIO_VDMABUF_H
- #include <uapi/linux/virtio_vdmabuf.h>
- #include <linux/hashtable.h>
- #include "../../drivers/vhost/vhost.h"
- #define UINT32_MAX ((u32)~0U)
- #define VIRTIO_VDMABUF_MAX_ID UINT32_MAX
- #define VIRTIO_VDMABUF_HASH_BITS 7
- #define VIRTIO_VDMABUF_CARVEOUT_NAME_LEN 16
- #define VIRTIO_VDMABUF_MAX_OPS 6
- #define VIRTIO_VDMABUF_MAX_BP_NUM (VIRTIO_VDAMBUF_MAX_ALLOC_SIZE / PAGE_SIZE)
- #define VIRTIO_VDMABUF_CARVEOUT_NAMES {{"vi"},{"vo"},{"enc"},{"dec"},{"gpu"},{"dpu"}}
- struct buf_pair {
- struct page *page;
- phys_addr_t addr;
- unsigned int size;
- };
- struct virtio_vdmabuf_buf {
- int vmid;
- size_t size;
- unsigned int buf_id;
- struct mutex lock;
- /* list of devices attached to this buffer */
- struct list_head attachments;
- struct dma_buf *dma_buf;
- /* validity of the buffer */
- bool valid;
- /* set if the buffer is imported from remote */
- bool imported;
- /* size of private */
- size_t sz_priv;
- /* private data associated with the exported buffer */
- void *priv;
- void *host;
- struct hlist_node node;
- /* real buf info */
- int heap_type;
- int carveout_type;
- int flags;
- int bp_num;
- struct buf_pair bp[];
- };
- struct virtio_vdmabuf_attachment {
- struct device *dev;
- struct sg_table *sgt;
- struct list_head list;
- };
- struct carveout_buf {
- phys_addr_t addr;
- unsigned int size;
- bool ready;
- };
- struct virtio_vdmabuf_event {
- struct list_head list;
- /*
- * 0: vmid
- * 1: buf_id
- * 2: heap_type
- * 3: carveout_type
- * 4: flags
- * 5: bp num
- */
- unsigned int op[VIRTIO_VDMABUF_MAX_OPS];
- struct buf_pair bp[];
- };
- struct virtio_vdmabuf_event_queue {
- wait_queue_head_t e_wait;
- struct list_head e_list;
- spinlock_t e_lock;
- struct mutex e_readlock;
- };
- /* driver information */
- struct virtio_vdmabuf_info {
- struct device *dev;
- struct list_head head_vdmabuf_list;
- struct list_head kvm_instances;
- spinlock_t local_lock;
- DECLARE_HASHTABLE(buf_list_local, VIRTIO_VDMABUF_HASH_BITS);
- spinlock_t import_lock;
- DECLARE_HASHTABLE(buf_list_import, VIRTIO_VDMABUF_HASH_BITS);
- void *priv;
- struct mutex g_mutex;
- bool host_ready;
- };
- struct vhost_vdmabuf;
- struct virtio_vdmabuf;
- /*
- * IOCTL definitions
- */
- typedef int (*vhost_vdmabuf_ioctl_t)(struct vhost_vdmabuf *vdmabuf,
- void *data);
- typedef int (*virtio_vdmabuf_ioctl_t)(struct virtio_vdmabuf *vdmabuf,
- void *data);
- struct vhost_vdmabuf_ioctl_desc {
- unsigned int cmd;
- int flags;
- vhost_vdmabuf_ioctl_t func;
- const char *name;
- };
- struct virtio_vdmabuf_ioctl_desc {
- unsigned int cmd;
- int flags;
- virtio_vdmabuf_ioctl_t func;
- const char *name;
- };
- #define VIRTIO_VDMABUF_IOCTL_DEF(ioctl, _func, _flags) \
- [_IOC_NR(ioctl)] = { \
- .cmd = ioctl, \
- .func = _func, \
- .flags = _flags, \
- .name = #ioctl \
- }
- /* msg structures */
- struct virtio_vdmabuf_msg {
- struct list_head list;
- unsigned int cmd;
- /*
- * 0: vmid
- * 1: buf_id
- * 2: heap_type
- * 3: carveout_type
- * 4: flags
- * 5: bp num
- */
- unsigned int op[VIRTIO_VDMABUF_MAX_OPS];
- struct buf_pair bp[];
- };
- enum {
- VDMABUF_VQ_RECV = 0,
- VDMABUF_VQ_SEND = 1,
- VDMABUF_VQ_MAX = 2,
- };
- enum virtio_vdmabuf_cmd {
- VIRTIO_VDMABUF_CMD_VMID_REQ,
- VIRTIO_VDMABUF_CMD_VMID_REPLY,
- VIRTIO_VDMABUF_CMD_IMPORT_REQ,
- VIRTIO_VDMABUF_CMD_IMPORT_REPLY,
- VIRTIO_VDMABUF_CMD_REL_NOTIFY,
- };
- struct virtio_vdmabuf {
- /* virtio device structure */
- struct virtio_device *vdev;
- /* virtual queue array */
- struct virtqueue *vqs[VDMABUF_VQ_MAX];
- /* ID of guest OS */
- unsigned int vmid;
- /* spin lock that needs to be acquired before accessing
- * virtual queue
- */
- spinlock_t vq_lock;
- struct mutex recv_lock;
- struct mutex send_lock;
- spinlock_t msg_list_lock;
- struct list_head msg_list;
- /* workqueue */
- struct workqueue_struct *wq;
- struct work_struct recv_work;
- struct work_struct send_work;
- struct work_struct send_msg_work;
- struct virtio_vdmabuf_event_queue *eq_import;
- };
- struct vhost_vdmabuf {
- struct vhost_dev dev;
- struct vhost_virtqueue vqs[VDMABUF_VQ_MAX];
- struct vhost_work send_work;
- struct virtio_vdmabuf_event_queue *eq_import;
- unsigned int vmid;
- struct list_head msg_list;
- struct list_head list;
- spinlock_t local_lock;
- DECLARE_HASHTABLE(buf_list_local, VIRTIO_VDMABUF_HASH_BITS);
- spinlock_t import_lock;
- DECLARE_HASHTABLE(buf_list_import, VIRTIO_VDMABUF_HASH_BITS);
- };
- static inline int vdmabuf_msg_size(int bp_num)
- {
- return sizeof(struct virtio_vdmabuf_msg) +
- sizeof(struct buf_pair) * bp_num;
- }
- /* guest api */
- static inline int
- virtio_vdmabuf_add_buf(struct virtio_vdmabuf_info *info,
- struct virtio_vdmabuf_buf *new,
- bool local)
- {
- if (local)
- hash_add(info->buf_list_local, &new->node, new->buf_id);
- else
- hash_add(info->buf_list_import, &new->node, new->buf_id);
- return 0;
- }
- static inline struct virtio_vdmabuf_buf
- *virtio_vdmabuf_find_buf(struct virtio_vdmabuf_info *info,
- unsigned int buf_id, bool local)
- {
- struct virtio_vdmabuf_buf *found;
- if (local) {
- hash_for_each_possible(info->buf_list_local, found, node, buf_id)
- if (found->buf_id == buf_id)
- return found;
- } else {
- hash_for_each_possible(info->buf_list_import, found, node, buf_id)
- if (found->buf_id == buf_id)
- return found;
- }
- return NULL;
- }
- static inline int
- virtio_vdmabuf_del_buf(struct virtio_vdmabuf_info *info,
- unsigned int buf_id, bool local)
- {
- struct virtio_vdmabuf_buf *found;
- found = virtio_vdmabuf_find_buf(info, buf_id, local);
- if (!found)
- return -ENOENT;
- hash_del(&found->node);
- return 0;
- }
- /* host api */
- static inline int
- vhost_vdmabuf_add_buf(struct vhost_vdmabuf *vdmabuf,
- struct virtio_vdmabuf_buf *new,
- bool local)
- {
- if (local)
- hash_add(vdmabuf->buf_list_local, &new->node, new->buf_id);
- else
- hash_add(vdmabuf->buf_list_import, &new->node, new->buf_id);
- return 0;
- }
- static inline struct virtio_vdmabuf_buf
- *vhost_vdmabuf_find_buf(struct vhost_vdmabuf *vdmabuf,
- unsigned int buf_id, bool local)
- {
- struct virtio_vdmabuf_buf *found;
- if (local) {
- hash_for_each_possible(vdmabuf->buf_list_local, found, node, buf_id)
- if (found->buf_id == buf_id)
- return found;
- } else {
- hash_for_each_possible(vdmabuf->buf_list_import, found, node, buf_id)
- if (found->buf_id == buf_id)
- return found;
- }
- return NULL;
- }
- static inline int
- vhost_vdmabuf_del_buf(struct vhost_vdmabuf *vdmabuf,
- unsigned int buf_id, bool local)
- {
- struct virtio_vdmabuf_buf *found;
- found = vhost_vdmabuf_find_buf(vdmabuf, buf_id, local);
- if (!found)
- return -ENOENT;
- hash_del(&found->node);
- return 0;
- }
- #endif
|