From: Chenbo Xia <chenbo.xia@intel.com>
To: dev@dpdk.org, thomas@monjalon.net, xuan.ding@intel.com,
xiuchun.lu@intel.com, cunming.liang@intel.com,
changpeng.liu@intel.com
Cc: zhihong.wang@intel.com
Subject: [dpdk-dev] [RFC v1 1/2] vfio_user: Add library for vfio over socket
Date: Fri, 14 Aug 2020 19:16:05 +0000 [thread overview]
Message-ID: <20200814191606.26312-2-chenbo.xia@intel.com> (raw)
In-Reply-To: <20200814191606.26312-1-chenbo.xia@intel.com>
Vfio-over-socket, also named as vfio-user, is a protocol for
emulating devices in a separate process outside of QEMU. The
main difference between APP using vfio-user and vfio kernel
module is that device manipulation is based on socket messages
for vfio-user but system calls for vfio kernel module.
This protocol has a server/client model and for now QEMU plays
the role of client. This patch implements vfio-user server of the
protocol in DPDK.
Signed-off-by: Chenbo Xia <chenbo.xia@intel.com>
Signed-off-by: Xiuchun Lu <xiuchun.lu@intel.com>
---
lib/librte_vfio_user/rte_vfio_user.h | 335 +++++++++++++++++++++++++++
1 file changed, 335 insertions(+)
create mode 100644 lib/librte_vfio_user/rte_vfio_user.h
diff --git a/lib/librte_vfio_user/rte_vfio_user.h b/lib/librte_vfio_user/rte_vfio_user.h
new file mode 100644
index 000000000..d36516084
--- /dev/null
+++ b/lib/librte_vfio_user/rte_vfio_user.h
@@ -0,0 +1,335 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#ifndef _VFIO_USER_H
+#define _VFIO_USER_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <linux/vfio.h>
+#include <net/if.h>
+#include <sys/queue.h>
+#include <sys/un.h>
+
+#define VFIO_USER_MSG_MAX_NREGIONS 8
+#define VFIO_USER_MAX_MEM_REGIONS 256
+#define VFIO_MAX_RW_DATA 256
+#define VFIO_USER_MAX_FD 64
+#define VFIO_USER_IRQ_MAX_DATA 64
+#define VFIO_USER_MAX_IRQ_FD 64
+
+typedef enum VFIO_USER_CMD_TYPE {
+ VFIO_USER_NONE = 0,
+ VFIO_USER_VERSION = 1,
+ VFIO_USER_DMA_MAP = 2,
+ VFIO_USER_DMA_UNMAP = 3,
+ VFIO_USER_DEVICE_GET_INFO = 4,
+ VFIO_USER_DEVICE_GET_REGION_INFO = 5,
+ VFIO_USER_DEVICE_GET_IRQ_INFO = 6,
+ VFIO_USER_DEVICE_SET_IRQS = 7,
+ VFIO_USER_REGION_READ = 8,
+ VFIO_USER_REGION_WRITE = 9,
+ VFIO_USER_DMA_READ = 10,
+ VFIO_USER_DMA_WRITE = 11,
+ VFIO_USER_VM_INTERRUPT = 12,
+ VFIO_USER_DEVICE_RESET = 13,
+ VFIO_USER_MAX = 14,
+} VFIO_USER_CMD_TYPE;
+
+struct vfio_user_mem_reg {
+ uint64_t gpa;
+ uint64_t size;
+ uint64_t fd_offset;
+ uint32_t protection; /* attributes in <sys/mman.h> */
+#define VFIO_USER_MEM_MAPPABLE (0x1 << 0)
+ uint32_t flags;
+};
+
+struct vfio_user_dev_info {
+ uint32_t argsz; /* Reserved in vfio-user */
+ uint32_t flags;
+ uint32_t num_regions;
+ uint32_t num_irqs;
+};
+
+struct vfio_user_reg_rw {
+ uint64_t reg_offset;
+ uint32_t reg_idx;
+ uint32_t size;
+ char data[VFIO_MAX_RW_DATA];
+};
+
+struct vfio_user_dma_rw {
+ uint64_t addr;
+ uint32_t size;
+ char data[VFIO_MAX_RW_DATA];
+};
+
+struct vfio_user_intr {
+ uint32_t type;
+ uint32_t vector;
+};
+
+typedef struct vfio_user_msg {
+ uint16_t dev_id;
+ uint16_t msg_id;
+ uint32_t cmd;
+ uint32_t size;
+#define VFIO_USER_REPLY_MASK (0x1 << 0)
+#define VFIO_USER_NEED_NO_RP (0x1 << 1)
+ uint32_t flags;
+ union {
+ struct vfio_user_mem_reg memory[VFIO_USER_MSG_MAX_NREGIONS];
+ struct vfio_user_dev_info dev_info;
+ struct vfio_region_info reg_info;
+ struct vfio_irq_info irq_info;
+ struct vfio_irq_set irq_set;
+ struct vfio_user_reg_rw reg_rw;
+ struct vfio_user_dma_rw dma_rw;
+ struct vfio_user_intr intr;
+ } payload;
+ int fds[VFIO_USER_MAX_FD];
+ int fd_num;
+} __attribute((packed)) VFIO_USER_MSG;
+
+#define VFIO_USER_MSG_HDR_SIZE offsetof(VFIO_USER_MSG, payload.dev_info)
+
+enum vfio_user_msg_handle_result {
+ VFIO_USER_MSG_HANDLE_ERR = -1,
+ VFIO_USER_MSG_HANDLE_OK = 0,
+ VFIO_USER_MSG_HANDLE_REPLY = 1,
+};
+
+struct vfio_user_mem_table_entry {
+ struct vfio_user_mem_reg region;
+ uint64_t host_user_addr;
+ void *mmap_addr;
+ uint64_t mmap_size;
+ int fd;
+};
+
+struct vfio_user_mem {
+ uint32_t entry_num;
+ struct vfio_user_mem_table_entry entry[VFIO_USER_MAX_MEM_REGIONS];
+};
+
+struct vfio_user_regions {
+ uint32_t reg_num;
+ struct vfio_region_info **reg_info;
+};
+
+struct vfio_user_irq_info {
+ uint32_t irq_num;
+ struct vfio_irq_info *irq_info;
+};
+
+struct vfio_user_irq_set {
+ uint32_t set_num;
+ struct vfio_irq_set **irq;
+ int fds[VFIO_USER_MAX_IRQ_FD];
+};
+
+struct vfio_user_irqs {
+ struct vfio_user_irq_info *info;
+ struct vfio_user_irq_set *set;
+};
+
+struct vfio_user_region_resource {
+ void *base;
+ uint32_t size;
+ int fd;
+};
+
+struct vfio_user_resource {
+ uint16_t resource_num;
+ struct vfio_user_region_resource res[];
+};
+
+struct vfio_user {
+ int dev_id;
+ int is_ready;
+#define IF_NAME_SZ (IFNAMSIZ > PATH_MAX ? IFNAMSIZ : PATH_MAX)
+ char sock_addr[IF_NAME_SZ];
+ const struct vfio_user_notify_ops *ops;
+ struct vfio_user_mem *mem;
+ struct vfio_user_dev_info *dev_info;
+ struct vfio_user_regions *reg;
+ struct vfio_user_irqs *irq;
+ struct vfio_user_resource *res;
+};
+
+struct vfio_user_notify_ops {
+ int (*new_device)(int dev_id); /* Add device */
+ void (*destroy_device)(int dev_id); /* Remove device */
+ int (*update_status)(int dev_id); /* Update device status */
+};
+
+typedef void (*vfio_user_log)(const char *format, ...);
+
+typedef int (*event_handler)(int fd, void *data);
+
+typedef struct listen_fd_info {
+ int fd;
+ uint32_t event;
+ event_handler ev_handle;
+ void *data;
+} FD_INFO;
+
+struct vfio_user_epoll {
+ int epfd;
+ FD_INFO fdinfo[VFIO_USER_MAX_FD];
+ uint32_t fd_num; /* Current num of listen_fd */
+ struct epoll_event *events;
+ pthread_mutex_t fd_mutex;
+};
+
+struct vfio_user_socket {
+ char *sock_addr;
+ struct sockaddr_un un;
+ int sock_fd;
+ int dev_id;
+};
+
+struct vfio_user_ep_sock {
+ struct vfio_user_epoll ep;
+ struct vfio_user_socket *sock[VFIO_USER_MAX_FD];
+ uint32_t sock_num;
+ pthread_mutex_t mutex;
+};
+
+/**
+ * Register a vfio-user device.
+ *
+ * @param sock_addr
+ * Unix domain socket address
+ * @param ops
+ * Notify ops for the device
+ * @param log
+ * Log callback for the device
+ * @return
+ * 0 on success, -1 on failure
+ */
+int rte_vfio_user_register(const char *sock_addr,
+ const struct vfio_user_notify_ops *ops,
+ vfio_user_log log);
+
+/**
+ * Unregister a vfio-user device.
+ *
+ * @param sock_addr
+ * Unix domain socket address
+ * @return
+ * 0 on success, -1 on failure
+ */
+int rte_vfio_user_unregister(const char *sock_addr);
+
+/**
+ * Start vfio-user handling for the device.
+ *
+ * This function triggers vfio-user message handling.
+ * @param sock_addr
+ * Unix domain socket address
+ * @return
+ * 0 on success, -1 on failure
+ */
+int rte_vfio_user_start(const char *sock_addr);
+
+/**
+ * Stop vfio-user handling for the device.
+ *
+ * This function stops vfio-user message handling.
+ * @param sock_addr
+ * Unix domain socket address
+ * @return
+ * 0 on success, -1 on failure
+ */
+int rte_vfio_user_stop(const char *sock_addr);
+
+/**
+ * Get the socket address for a vfio-user device.
+ *
+ * @param dev_id
+ * Vfio-user device ID
+ * @param buf
+ * Buffer to store socket address
+ * @param len
+ * The len of buf
+ * @return
+ * 0 on success, -1 on failure
+ */
+int rte_vfio_get_sock_addr(int dev_id, char *buf, size_t len);
+
+/**
+ * Get the memory table of a vfio-user device.
+ *
+ * @param dev_id
+ * Vfio-user device ID
+ * @return
+ * Pointer to memory table on success, NULL on failure
+ */
+struct vfio_user_mem *rte_vfio_user_get_mem_table(int dev_id);
+
+/**
+ * Get the irq set of a vfio-user device.
+ *
+ * @param dev_id
+ * Vfio-user device ID
+ * @return
+ * Pointer to irq set on success, NULL on failure
+ */
+struct vfio_user_irq_set *rte_vfio_user_get_irq(int dev_id);
+
+/**
+ * Set the device info for a vfio-user device.
+ *
+ * @param sock_addr
+ * Unix domain socket address
+ * @param dev_info
+ * Device info for the vfio-user device
+ * @return
+ * 0 on success, -1 on failure
+ */
+int rte_vfio_user_set_dev_info(const char *sock_addr,
+ struct vfio_user_dev_info *dev_info);
+
+/**
+ * Set the region info for a vfio-user device.
+ *
+ * @param sock_addr
+ * Unix domain socket address
+ * @param reg
+ * Region info for the vfio-user device
+ * @return
+ * 0 on success, -1 on failure
+ */
+int rte_vfio_user_set_reg_info(const char *sock_addr,
+ struct vfio_user_regions *reg);
+
+/**
+ * Set the irq info for a vfio-user device.
+ *
+ * @param sock_addr
+ * Unix domain socket address
+ * @param irq
+ * IRQ info for the vfio-user device
+ * @return
+ * 0 on success, -1 on failure
+ */
+int rte_vfio_user_set_irq_info(const char *sock_addr,
+ struct vfio_user_irq_info *irq);
+
+/**
+ * Set the device resource for a vfio-user device.
+ *
+ * @param sock_addr
+ * Unix domain socket address
+ * @param res
+ * Resource info for the vfio-user device
+ * @return
+ * 0 on success, -1 on failure
+ */
+int rte_vfio_user_set_resource(const char *sock_addr,
+ struct vfio_user_resource *res);
+
+#endif
--
2.17.1
next prev parent reply other threads:[~2020-08-14 10:27 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-14 19:16 [dpdk-dev] [RFC v1 0/2] Add device emulation support in DPDK Chenbo Xia
2020-08-14 15:00 ` Stephen Hemminger
2020-08-17 2:58 ` Xia, Chenbo
2020-08-14 19:16 ` Chenbo Xia [this message]
2020-08-14 19:16 ` [dpdk-dev] [RFC v1 2/2] emudev: Add library for emulated device Chenbo Xia
2020-09-02 21:10 ` [dpdk-dev] [RFC v1 0/2] Add device emulation support in DPDK Thomas Monjalon
2020-09-03 6:29 ` Xia, Chenbo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200814191606.26312-2-chenbo.xia@intel.com \
--to=chenbo.xia@intel.com \
--cc=changpeng.liu@intel.com \
--cc=cunming.liang@intel.com \
--cc=dev@dpdk.org \
--cc=thomas@monjalon.net \
--cc=xiuchun.lu@intel.com \
--cc=xuan.ding@intel.com \
--cc=zhihong.wang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).