1438d863fSJohn Levon #ifndef VFIO_USER_PROXY_H 2438d863fSJohn Levon #define VFIO_USER_PROXY_H 3438d863fSJohn Levon 4438d863fSJohn Levon /* 5438d863fSJohn Levon * vfio protocol over a UNIX socket. 6438d863fSJohn Levon * 7438d863fSJohn Levon * Copyright © 2018, 2021 Oracle and/or its affiliates. 8438d863fSJohn Levon * 9438d863fSJohn Levon * SPDX-License-Identifier: GPL-2.0-or-later 10438d863fSJohn Levon */ 11438d863fSJohn Levon 12438d863fSJohn Levon #include "io/channel.h" 13438d863fSJohn Levon #include "io/channel-socket.h" 14438d863fSJohn Levon 153bdb738bSJohn Levon #include "qemu/queue.h" 160b3d881aSJohn Levon #include "qemu/sockets.h" 173bdb738bSJohn Levon #include "qemu/thread.h" 18667866d6SJohn Levon #include "hw/vfio/vfio-device.h" 190b3d881aSJohn Levon #include "hw/vfio-user/protocol.h" 200b3d881aSJohn Levon 21438d863fSJohn Levon typedef struct { 22438d863fSJohn Levon int send_fds; 23438d863fSJohn Levon int recv_fds; 24438d863fSJohn Levon int *fds; 25438d863fSJohn Levon } VFIOUserFDs; 26438d863fSJohn Levon 27438d863fSJohn Levon enum msg_type { 28438d863fSJohn Levon VFIO_MSG_NONE, 29438d863fSJohn Levon VFIO_MSG_ASYNC, 30438d863fSJohn Levon VFIO_MSG_WAIT, 31438d863fSJohn Levon VFIO_MSG_NOWAIT, 32438d863fSJohn Levon VFIO_MSG_REQ, 33438d863fSJohn Levon }; 34438d863fSJohn Levon 35438d863fSJohn Levon typedef struct VFIOUserMsg { 36438d863fSJohn Levon QTAILQ_ENTRY(VFIOUserMsg) next; 370b3d881aSJohn Levon VFIOUserHdr *hdr; 38438d863fSJohn Levon VFIOUserFDs *fds; 39438d863fSJohn Levon uint32_t rsize; 40438d863fSJohn Levon uint32_t id; 41438d863fSJohn Levon QemuCond cv; 42438d863fSJohn Levon bool complete; 4336227628SJohn Levon bool pending; 44438d863fSJohn Levon enum msg_type type; 45438d863fSJohn Levon } VFIOUserMsg; 46438d863fSJohn Levon 47438d863fSJohn Levon 48438d863fSJohn Levon enum proxy_state { 49438d863fSJohn Levon VFIO_PROXY_CONNECTED = 1, 50438d863fSJohn Levon VFIO_PROXY_ERROR = 2, 51438d863fSJohn Levon VFIO_PROXY_CLOSING = 3, 52438d863fSJohn Levon VFIO_PROXY_CLOSED = 4, 53438d863fSJohn Levon }; 54438d863fSJohn Levon 55438d863fSJohn Levon typedef QTAILQ_HEAD(VFIOUserMsgQ, VFIOUserMsg) VFIOUserMsgQ; 56438d863fSJohn Levon 57438d863fSJohn Levon typedef struct VFIOUserProxy { 58438d863fSJohn Levon QLIST_ENTRY(VFIOUserProxy) next; 59438d863fSJohn Levon char *sockname; 60438d863fSJohn Levon struct QIOChannel *ioc; 61438d863fSJohn Levon void (*request)(void *opaque, VFIOUserMsg *msg); 62438d863fSJohn Levon void *req_arg; 6336227628SJohn Levon uint64_t max_xfer_size; 6436227628SJohn Levon uint64_t max_send_fds; 6536227628SJohn Levon uint64_t max_dma; 6636227628SJohn Levon uint64_t dma_pgsizes; 6736227628SJohn Levon uint64_t max_bitmap; 6836227628SJohn Levon uint64_t migr_pgsize; 69438d863fSJohn Levon int flags; 703358d926SJohn Levon uint32_t wait_time; 71438d863fSJohn Levon QemuCond close_cv; 72438d863fSJohn Levon AioContext *ctx; 73438d863fSJohn Levon QEMUBH *req_bh; 7418e899e6SJohn Levon bool async_ops; 75438d863fSJohn Levon 76438d863fSJohn Levon /* 77438d863fSJohn Levon * above only changed when BQL is held 78438d863fSJohn Levon * below are protected by per-proxy lock 79438d863fSJohn Levon */ 80438d863fSJohn Levon QemuMutex lock; 81438d863fSJohn Levon VFIOUserMsgQ free; 82438d863fSJohn Levon VFIOUserMsgQ pending; 83438d863fSJohn Levon VFIOUserMsgQ incoming; 84438d863fSJohn Levon VFIOUserMsgQ outgoing; 85438d863fSJohn Levon VFIOUserMsg *last_nowait; 860b3d881aSJohn Levon VFIOUserMsg *part_recv; 870b3d881aSJohn Levon size_t recv_left; 88438d863fSJohn Levon enum proxy_state state; 89438d863fSJohn Levon } VFIOUserProxy; 90438d863fSJohn Levon 91438d863fSJohn Levon /* VFIOProxy flags */ 92438d863fSJohn Levon #define VFIO_PROXY_CLIENT 0x1 9336227628SJohn Levon #define VFIO_PROXY_FORCE_QUEUED 0x4 94*98a906d9SJohn Levon #define VFIO_PROXY_NO_POST 0x8 95438d863fSJohn Levon 960b3d881aSJohn Levon typedef struct VFIODevice VFIODevice; 970b3d881aSJohn Levon 98438d863fSJohn Levon VFIOUserProxy *vfio_user_connect_dev(SocketAddress *addr, Error **errp); 99438d863fSJohn Levon void vfio_user_disconnect(VFIOUserProxy *proxy); 1000b3d881aSJohn Levon void vfio_user_set_handler(VFIODevice *vbasedev, 1010b3d881aSJohn Levon void (*handler)(void *opaque, VFIOUserMsg *msg), 1020b3d881aSJohn Levon void *reqarg); 10336227628SJohn Levon bool vfio_user_validate_version(VFIOUserProxy *proxy, Error **errp); 104438d863fSJohn Levon 10518e899e6SJohn Levon VFIOUserFDs *vfio_user_getfds(int numfds); 106c6ac52a4SJohn Levon void vfio_user_putfds(VFIOUserMsg *msg); 10718e899e6SJohn Levon 108*98a906d9SJohn Levon void vfio_user_disable_posted_writes(VFIOUserProxy *proxy); 109*98a906d9SJohn Levon 1103bdb738bSJohn Levon void vfio_user_request_msg(VFIOUserHdr *hdr, uint16_t cmd, 1113bdb738bSJohn Levon uint32_t size, uint32_t flags); 11218e899e6SJohn Levon void vfio_user_wait_reqs(VFIOUserProxy *proxy); 1133bdb738bSJohn Levon bool vfio_user_send_wait(VFIOUserProxy *proxy, VFIOUserHdr *hdr, 1143bdb738bSJohn Levon VFIOUserFDs *fds, int rsize, Error **errp); 11518e899e6SJohn Levon bool vfio_user_send_nowait(VFIOUserProxy *proxy, VFIOUserHdr *hdr, 11618e899e6SJohn Levon VFIOUserFDs *fds, int rsize, Error **errp); 117*98a906d9SJohn Levon bool vfio_user_send_async(VFIOUserProxy *proxy, VFIOUserHdr *hdr, 118*98a906d9SJohn Levon VFIOUserFDs *fds, Error **errp); 119*98a906d9SJohn Levon 120c6ac52a4SJohn Levon void vfio_user_send_reply(VFIOUserProxy *proxy, VFIOUserHdr *hdr, int size); 121c6ac52a4SJohn Levon void vfio_user_send_error(VFIOUserProxy *proxy, VFIOUserHdr *hdr, int error); 1223bdb738bSJohn Levon 123438d863fSJohn Levon #endif /* VFIO_USER_PROXY_H */ 124