DPDK patches and discussions
 help / color / mirror / Atom feed
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


  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).