All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chenbo Xia <chenbo.xia@intel.com>
To: dev@dpdk.org, thomas@monjalon.net, david.marchand@redhat.com
Cc: stephen@networkplumber.org, cunming.liang@intel.com,
	xiuchun.lu@intel.com, miao.li@intel.com, jingjing.wu@intel.com
Subject: [dpdk-dev] [PATCH 8/9] test/vfio_user: introduce functional test
Date: Fri, 18 Dec 2020 15:38:50 +0800	[thread overview]
Message-ID: <20201218073851.93609-9-chenbo.xia@intel.com> (raw)
In-Reply-To: <20201218073851.93609-1-chenbo.xia@intel.com>

This patch introduces functional test for vfio_user client and
server. Note that the test can only be run with server and client
both started and server should be started first.

Signed-off-by: Chenbo Xia <chenbo.xia@intel.com>
Signed-off-by: Xiuchun Lu <xiuchun.lu@intel.com>
---
 app/test/meson.build      |   4 +
 app/test/test_vfio_user.c | 646 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 650 insertions(+)
 create mode 100644 app/test/test_vfio_user.c

diff --git a/app/test/meson.build b/app/test/meson.build
index 94fd39fecb..f5b15ac44c 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -138,6 +138,7 @@ test_sources = files('commands.c',
 	'test_trace.c',
 	'test_trace_register.c',
 	'test_trace_perf.c',
+	'test_vfio_user.c',
 	'test_version.c',
 	'virtual_pmd.c'
 )
@@ -173,6 +174,7 @@ test_deps = ['acl',
 	'ring',
 	'security',
 	'stack',
+	'vfio_user',
 	'telemetry',
 	'timer'
 ]
@@ -266,6 +268,8 @@ fast_tests = [
         ['service_autotest', true],
         ['thash_autotest', true],
         ['trace_autotest', true],
+        ['vfio_user_autotest_client', false],
+        ['vfio_user_autotest_server', false],
 ]
 
 perf_test_names = [
diff --git a/app/test/test_vfio_user.c b/app/test/test_vfio_user.c
new file mode 100644
index 0000000000..ee245e437d
--- /dev/null
+++ b/app/test/test_vfio_user.c
@@ -0,0 +1,646 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#include <inttypes.h>
+#include <limits.h>
+#include <stdatomic.h>
+#include <sys/eventfd.h>
+#include <sys/mman.h>
+
+#include <rte_vfio_user.h>
+#include <rte_malloc.h>
+#include <rte_hexdump.h>
+#include <rte_pause.h>
+#include <rte_log.h>
+
+#include "test.h"
+
+#define REGION_SIZE 0x100
+
+struct server_mem_tb {
+	uint32_t entry_num;
+	struct rte_vfio_user_mtb_entry entry[];
+};
+
+static const char test_sock[] = "/tmp/dpdk_vfio_test";
+struct server_mem_tb *server_mem;
+int server_irqfd;
+atomic_uint test_failed;
+atomic_uint server_destroyed;
+
+static int test_set_dev_info(const char *sock,
+	struct vfio_device_info *info)
+{
+	int ret;
+
+	info->argsz = sizeof(*info);
+	info->flags = VFIO_DEVICE_FLAGS_RESET | VFIO_DEVICE_FLAGS_PCI;
+	info->num_irqs = VFIO_PCI_NUM_IRQS;
+	info->num_regions = VFIO_PCI_NUM_REGIONS;
+	ret = rte_vfio_user_set_dev_info(sock, info);
+	if (ret) {
+		printf("Failed to set device info\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static ssize_t test_dev_cfg_rw(struct rte_vfio_user_reg_info *reg, char *buf,
+	size_t count, loff_t pos, bool iswrite)
+{
+	char *loc = (char *)reg->base + pos;
+
+	if (!iswrite) {
+		if (pos + count > reg->info->size)
+			return -1;
+		memcpy(buf, loc, count);
+		return count;
+	}
+
+	memcpy(loc, buf, count);
+	return count;
+}
+
+static int test_set_reg_info(const char *sock_addr,
+	struct rte_vfio_user_regions *reg)
+{
+	struct rte_vfio_user_reg_info *reg_info;
+	void *cfg_base = NULL;
+	uint32_t i, j, sz = 0, reg_sz = REGION_SIZE;
+	int ret;
+
+	reg->reg_num = VFIO_PCI_NUM_REGIONS;
+	sz = sizeof(struct vfio_region_info);
+
+	for (i = 0; i < reg->reg_num; i++) {
+		reg_info = &reg->reg_info[i];
+
+		reg_info->info = rte_zmalloc(NULL, sz, 0);
+		if (!reg_info->info) {
+			printf("Failed to alloc vfio region info\n");
+			goto err;
+		}
+
+		reg_info->priv = NULL;
+		reg_info->fd = -1;
+		reg_info->info->argsz = sz;
+		reg_info->info->cap_offset = sz;
+		reg_info->info->index = i;
+		reg_info->info->offset = 0;
+		reg_info->info->flags = VFIO_REGION_INFO_FLAG_READ |
+			VFIO_REGION_INFO_FLAG_WRITE;
+
+		if (i == VFIO_PCI_CONFIG_REGION_INDEX) {
+			cfg_base = rte_zmalloc(NULL, reg_sz, 0);
+			if (!cfg_base) {
+				printf("Failed to alloc cfg space\n");
+				goto err;
+			}
+			reg_info->base = cfg_base;
+			reg_info->rw = test_dev_cfg_rw;
+			reg_info->info->size = reg_sz;
+		} else {
+			reg_info->base = NULL;
+			reg_info->rw = NULL;
+			reg_info->info->size = 0;
+		}
+	}
+
+	ret = rte_vfio_user_set_reg_info(sock_addr, reg);
+	if (ret) {
+		printf("Failed to set region info\n");
+		return -1;
+	}
+
+	return 0;
+err:
+	for (j = 0; j < i; j++)
+		rte_free(reg->reg_info[i].info);
+	rte_free(cfg_base);
+	return -1;
+}
+
+static void cleanup_reg(struct rte_vfio_user_regions *reg)
+{
+	struct rte_vfio_user_reg_info *reg_info;
+	uint32_t i;
+
+	for (i = 0; i < reg->reg_num; i++) {
+		reg_info = &reg->reg_info[i];
+
+		rte_free(reg_info->info);
+
+		if (i == VFIO_PCI_CONFIG_REGION_INDEX)
+			rte_free(reg_info->base);
+	}
+}
+
+static int test_set_irq_info(const char *sock,
+	struct rte_vfio_user_irq_info *info)
+{
+	struct vfio_irq_info *irq_info;
+	int ret;
+	uint32_t i;
+
+	info->irq_num = VFIO_PCI_NUM_IRQS;
+	for (i = 0; i < info->irq_num; i++) {
+		irq_info = &info->irq_info[i];
+		irq_info->argsz = sizeof(irq_info);
+		irq_info->index = i;
+
+		if (i == VFIO_PCI_MSIX_IRQ_INDEX) {
+			irq_info->flags = VFIO_IRQ_INFO_EVENTFD |
+				VFIO_IRQ_INFO_NORESIZE;
+			irq_info->count = 1;
+		} else {
+			irq_info->flags = 0;
+			irq_info->count = 0;
+		}
+	}
+
+	ret = rte_vfio_user_set_irq_info(sock, info);
+	if (ret) {
+		printf("Failed to set irq info\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int test_get_mem(int dev_id)
+{
+	const struct rte_vfio_user_mem *mem;
+	uint32_t entry_sz;
+
+	mem = rte_vfio_user_get_mem_table(dev_id);
+	if (!mem) {
+		printf("Failed to get memory table\n");
+		return -1;
+	}
+
+	entry_sz = sizeof(struct rte_vfio_user_mtb_entry) * mem->entry_num;
+	server_mem = rte_zmalloc(NULL, sizeof(*server_mem) + entry_sz, 0);
+
+	memcpy(server_mem->entry, mem->entry, entry_sz);
+	server_mem->entry_num = mem->entry_num;
+
+	return 0;
+}
+
+static int test_get_irq(int dev_id)
+{
+	int ret;
+
+	server_irqfd = -1;
+	ret = rte_vfio_user_get_irq(dev_id, VFIO_PCI_MSIX_IRQ_INDEX, 1,
+		&server_irqfd);
+	if (ret) {
+		printf("Failed to get IRQ\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int test_create_device(int dev_id)
+{
+	char sock[PATH_MAX];
+
+	RTE_LOG(DEBUG, USER1, "Device created\n");
+
+	if (rte_vfio_get_sock_addr(dev_id, sock, sizeof(sock))) {
+		printf("Failed to get socket addr\n");
+		goto err;
+	}
+
+	if (strcmp(sock, test_sock)) {
+		printf("Wrong socket addr\n");
+		goto err;
+	}
+
+	printf("Get socket address: TEST OK\n");
+
+	return 0;
+err:
+	atomic_store(&test_failed, 1);
+	return -1;
+}
+
+static void test_destroy_device(int dev_id __rte_unused)
+{
+	int ret;
+
+	RTE_LOG(DEBUG, USER1, "Device destroyed\n");
+
+	ret = test_get_mem(dev_id);
+	if (ret)
+		goto err;
+
+	printf("Get memory table: TEST OK\n");
+
+	ret = test_get_irq(dev_id);
+	if (ret)
+		goto err;
+
+	printf("Get IRQ: TEST OK\n");
+
+	atomic_store(&server_destroyed, 1);
+	return;
+err:
+	atomic_store(&test_failed, 1);
+}
+
+static int test_update_device(int dev_id __rte_unused)
+{
+	RTE_LOG(DEBUG, USER1, "Device updated\n");
+
+	return 0;
+}
+
+static int test_lock_dp(int dev_id __rte_unused, int lock)
+{
+	RTE_LOG(DEBUG, USER1, "Device data path %slocked\n", lock ? "" : "un");
+	return 0;
+}
+
+static int test_reset_device(int dev_id __rte_unused)
+{
+	RTE_LOG(DEBUG, USER1, "Device reset\n");
+	return 0;
+}
+
+const struct rte_vfio_user_notify_ops test_vfio_ops = {
+	.new_device = test_create_device,
+	.destroy_device = test_destroy_device,
+	.update_status = test_update_device,
+	.lock_dp = test_lock_dp,
+	.reset_device = test_reset_device,
+};
+
+static int
+test_vfio_user_server(void)
+{
+	struct vfio_device_info dev_info;
+	struct rte_vfio_user_regions *reg;
+	struct rte_vfio_user_reg_info *reg_info;
+	struct vfio_region_info *info;
+	struct rte_vfio_user_irq_info *irq_info;
+	struct rte_vfio_user_mtb_entry *ent;
+	int ret, err;
+	uint32_t i;
+
+	atomic_init(&test_failed, 0);
+	atomic_init(&server_destroyed, 0);
+
+	ret = rte_vfio_user_register(test_sock, &test_vfio_ops);
+	if (ret) {
+		printf("Failed to register\n");
+		ret = TEST_FAILED;
+		goto err_regis;
+	}
+
+	printf("Register device: TEST OK\n");
+
+	reg = rte_zmalloc(NULL, sizeof(*reg) + VFIO_PCI_NUM_REGIONS *
+		sizeof(struct rte_vfio_user_reg_info), 0);
+	if (!reg) {
+		printf("Failed to alloc regions\n");
+		ret = TEST_FAILED;
+		goto err_reg;
+	}
+
+	irq_info = rte_zmalloc(NULL, sizeof(*irq_info) + VFIO_PCI_NUM_IRQS *
+		sizeof(struct vfio_irq_info), 0);
+	if (!irq_info) {
+		printf("Failed to alloc irq info\n");
+		ret = TEST_FAILED;
+		goto err_irq;
+	}
+
+	if (test_set_dev_info(test_sock, &dev_info)) {
+		ret = TEST_FAILED;
+		goto err_set;
+	}
+
+	printf("Set device info: TEST OK\n");
+
+	if (test_set_reg_info(test_sock, reg)) {
+		ret = TEST_FAILED;
+		goto err_set;
+	}
+
+	printf("Set device info: TEST OK\n");
+
+	if (test_set_irq_info(test_sock, irq_info)) {
+		ret = TEST_FAILED;
+		goto err;
+	}
+
+	printf("Set irq info: TEST OK\n");
+
+	ret = rte_vfio_user_start(test_sock);
+	if (ret) {
+		printf("Failed to start\n");
+		ret = TEST_FAILED;
+		goto err;
+	}
+
+	printf("Start device: TEST OK\n");
+
+	while (atomic_load(&test_failed) == 0 &&
+		atomic_load(&server_destroyed) == 0)
+		rte_pause();
+
+	if (atomic_load(&test_failed) == 1) {
+		printf("Test failed during device running\n");
+		ret = TEST_FAILED;
+		goto err;
+	}
+
+	printf("=================================\n");
+	printf("Device layout:\n");
+	printf("=================================\n");
+	printf("%u regions, %u IRQs\n", dev_info.num_regions,
+		dev_info.num_irqs);
+	printf("=================================\n");
+
+	reg_info = &reg->reg_info[VFIO_PCI_CONFIG_REGION_INDEX];
+	info = reg_info->info;
+	printf("Configuration Space:\nsize : 0x%llx, prot: %s%s\n",
+		info->size,
+		(info->flags & VFIO_REGION_INFO_FLAG_READ) ? "read/" : "",
+		(info->flags & VFIO_REGION_INFO_FLAG_WRITE) ? "write" : "");
+	rte_hexdump(stdout, "Content", (const void *)reg_info->base,
+		info->size);
+
+	printf("=================================\n");
+	printf("DMA memory table (Entry num: %u):\n", server_mem->entry_num);
+
+	for (i = 0; i < server_mem->entry_num; i++) {
+		ent = &server_mem->entry[i];
+		printf("(Entry %u) gpa: 0x%" PRIx64
+			", size: 0x%" PRIx64 ", hva: 0x%" PRIx64 "\n"
+			", mmap_addr: 0x%" PRIx64 ", mmap_size: 0x%" PRIx64
+			", fd: %d\n", i, ent->gpa, ent->size,
+			ent->host_user_addr, (uint64_t)ent->mmap_addr,
+			ent->mmap_size, ent->fd);
+	}
+
+	printf("=================================\n");
+	printf("MSI-X Interrupt:\nNumber: %u, irqfd: %s\n",
+		irq_info->irq_info[VFIO_PCI_MSIX_IRQ_INDEX].count,
+		server_irqfd == -1 ? "Invalid" : "Valid");
+
+	ret = TEST_SUCCESS;
+
+err:
+	cleanup_reg(reg);
+err_set:
+	rte_free(irq_info);
+err_irq:
+	rte_free(reg);
+err_reg:
+	err = rte_vfio_user_unregister(test_sock);
+	if (err)
+		ret = TEST_FAILED;
+	else
+		printf("Unregister device: TEST OK\n");
+err_regis:
+	return ret;
+}
+
+static int test_get_dev_info(int dev_id, struct vfio_device_info *info)
+{
+	int ret;
+
+	ret = rte_vfio_user_get_dev_info(dev_id, info);
+	if (ret) {
+		printf("Failed to get device info\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int test_get_reg_info(int dev_id, struct vfio_region_info *info)
+{
+	int ret, fd = -1;
+
+	info->index = VFIO_PCI_CONFIG_REGION_INDEX;
+	info->argsz = sizeof(*info);
+	ret = rte_vfio_user_get_reg_info(dev_id, info, &fd);
+	if (ret) {
+		printf("Failed to get region info\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int test_get_irq_info(int dev_id, struct vfio_irq_info *info)
+{
+	int ret;
+
+	info->index = VFIO_PCI_MSIX_IRQ_INDEX;
+	ret = rte_vfio_user_get_irq_info(dev_id, info);
+	if (ret) {
+		printf("Failed to get irq info\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int test_set_irqs(int dev_id, struct vfio_irq_set *set, int *fd)
+{
+	int ret;
+
+	*fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
+	if (*fd < 0) {
+		printf("Failed to create eventfd\n");
+		return -1;
+	}
+
+	set->argsz = sizeof(*set) + sizeof(int);
+	set->count = 1;
+	set->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
+	set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+	set->start = 0;
+	memcpy(set->data, fd, sizeof(*fd));
+
+	ret = rte_vfio_user_set_irqs(dev_id, set);
+	if (ret) {
+		printf("Failed to set irqs\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int test_dma_map_unmap(int dev_id, struct rte_vfio_user_mem_reg *mem)
+{
+	int ret, fd = -1;
+
+	mem->fd_offset = 0;
+	mem->flags = 0;
+	mem->gpa = 0x12345678;
+	mem->protection = PROT_READ | PROT_WRITE;
+	mem->size = 0x10000;
+
+	/* Map -> Unmap -> Map */
+	ret = rte_vfio_user_dma_map(dev_id, mem, &fd, 1);
+	if (ret) {
+		printf("Failed to dma map\n");
+		return -1;
+	}
+
+	ret = rte_vfio_user_dma_unmap(dev_id, mem, 1);
+	if (ret) {
+		printf("Failed to dma unmap\n");
+		return -1;
+	}
+
+	ret = rte_vfio_user_dma_map(dev_id, mem, &fd, 1);
+	if (ret) {
+		printf("Failed to dma re-map\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int test_region_read_write(int dev_id, void *read_data, uint64_t sz)
+{
+	int ret;
+	uint32_t data = 0x1A2B3C4D, idx = VFIO_PCI_CONFIG_REGION_INDEX;
+
+	ret = rte_vfio_user_region_write(dev_id, idx, 0, 4, (void *)&data);
+	if (ret) {
+		printf("Failed to write region\n");
+		return -1;
+	}
+
+	ret = rte_vfio_user_region_read(dev_id, idx, 0, sz, read_data);
+	if (ret) {
+		printf("Failed to read region\n");
+		return -1;
+	}
+
+	return 0;
+}
+static int
+test_vfio_user_client(void)
+{
+	int ret = 0, dev_id, fd = -1;
+	struct vfio_device_info dev_info;
+	struct vfio_irq_info irq_info;
+	struct rte_vfio_user_mem_reg mem;
+	struct vfio_irq_set *set;
+	struct vfio_region_info reg_info;
+	void *data;
+
+	ret = rte_vfio_user_attach_dev(test_sock);
+	if (ret) {
+		printf("Failed to attach device\n");
+		return TEST_FAILED;
+	}
+
+	printf("Attach device: TEST OK\n");
+
+	dev_id = ret;
+	ret = rte_vfio_user_reset(dev_id);
+	if (ret) {
+		printf("Failed to reset device\n");
+		return TEST_FAILED;
+	}
+
+	printf("Reset device: TEST OK\n");
+
+	if (test_get_dev_info(dev_id, &dev_info))
+		return TEST_FAILED;
+
+	printf("Get device info: TEST OK\n");
+
+	if (test_get_reg_info(dev_id, &reg_info))
+		return TEST_FAILED;
+
+	printf("Get region info: TEST OK\n");
+
+	if (test_get_irq_info(dev_id, &irq_info))
+		return TEST_FAILED;
+
+	printf("Get irq info: TEST OK\n");
+
+	set = rte_zmalloc(NULL, sizeof(*set) + sizeof(int), 0);
+	if (!set) {
+		printf("Failed to allocate irq set\n");
+		return TEST_FAILED;
+	}
+
+	data = rte_zmalloc(NULL, reg_info.size, 0);
+	if (!data) {
+		printf("Failed to allcate data\n");
+		ret = TEST_FAILED;
+		goto err_data;
+	}
+
+	if (test_set_irqs(dev_id, set, &fd)) {
+		ret = TEST_FAILED;
+		goto err;
+	}
+
+	printf("Set irqs: TEST OK\n");
+
+	if (test_dma_map_unmap(dev_id, &mem)) {
+		ret = TEST_FAILED;
+		goto err;
+	}
+
+	printf("DMA map/unmap: TEST OK\n");
+
+	if (test_region_read_write(dev_id, data, reg_info.size)) {
+		ret = TEST_FAILED;
+		goto err;
+	}
+
+	printf("Region read/write: TEST OK\n");
+
+	printf("=================================\n");
+	printf("Device layout:\n");
+	printf("=================================\n");
+	printf("%u regions, %u IRQs\n", dev_info.num_regions,
+		dev_info.num_irqs);
+	printf("=================================\n");
+	printf("Configuration Space:\nsize : 0x%llx, prot: %s%s\n",
+		reg_info.size,
+		(reg_info.flags & VFIO_REGION_INFO_FLAG_READ) ? "read/" : "",
+		(reg_info.flags & VFIO_REGION_INFO_FLAG_WRITE) ? "write" : "");
+	rte_hexdump(stdout, "Content", (const void *)data, reg_info.size);
+
+	printf("=================================\n");
+	printf("DMA memory table (Entry num: 1):\ngpa: 0x%" PRIx64
+		", size: 0x%" PRIx64 ", fd: -1, fd_offset:0x%" PRIx64 "\n",
+		mem.gpa, mem.size, mem.fd_offset);
+	printf("=================================\n");
+	printf("MSI-X Interrupt:\nNumber: %u, irqfd: %s\n", irq_info.count,
+		fd == -1 ? "Invalid" : "Valid");
+
+	ret = rte_vfio_user_detach_dev(dev_id);
+	if (ret) {
+		printf("Failed to detach device\n");
+		ret = TEST_FAILED;
+		goto err;
+	}
+
+	printf("Device detach: TEST OK\n");
+err:
+	rte_free(data);
+err_data:
+	rte_free(set);
+	return ret;
+}
+
+REGISTER_TEST_COMMAND(vfio_user_autotest_client, test_vfio_user_client);
+REGISTER_TEST_COMMAND(vfio_user_autotest_server, test_vfio_user_server);
-- 
2.17.1


  parent reply	other threads:[~2020-12-18  7:56 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-18  7:38 [dpdk-dev] [PATCH 0/9] Introduce vfio-user library Chenbo Xia
2020-12-18  7:38 ` [dpdk-dev] [PATCH 1/9] lib: introduce " Chenbo Xia
2020-12-18 17:13   ` Stephen Hemminger
2020-12-19  6:12     ` Xia, Chenbo
2020-12-18 17:17   ` Stephen Hemminger
2020-12-19  6:25     ` Xia, Chenbo
2020-12-18  7:38 ` [dpdk-dev] [PATCH 2/9] vfio_user: implement lifecycle related APIs Chenbo Xia
2021-01-05  8:34   ` Xing, Beilei
2021-01-05  9:58     ` Xia, Chenbo
2020-12-18  7:38 ` [dpdk-dev] [PATCH 3/9] vfio_user: implement device and region " Chenbo Xia
2021-01-06  5:51   ` Xing, Beilei
2021-01-06  7:50     ` Xia, Chenbo
2020-12-18  7:38 ` [dpdk-dev] [PATCH 4/9] vfio_user: implement DMA table and socket address API Chenbo Xia
2020-12-18  7:38 ` [dpdk-dev] [PATCH 5/9] vfio_user: implement interrupt related APIs Chenbo Xia
2020-12-30  1:04   ` Wu, Jingjing
2020-12-30  2:31     ` Xia, Chenbo
2020-12-18  7:38 ` [dpdk-dev] [PATCH 6/9] vfio_user: add client APIs of device attach/detach Chenbo Xia
2020-12-18  7:38 ` [dpdk-dev] [PATCH 7/9] vfio_user: add client APIs of DMA/IRQ/region Chenbo Xia
2021-01-07  2:41   ` Xing, Beilei
2021-01-07  7:26     ` Xia, Chenbo
2020-12-18  7:38 ` Chenbo Xia [this message]
2020-12-18  7:38 ` [dpdk-dev] [PATCH 9/9] doc: add vfio-user library guide Chenbo Xia
2021-01-06  5:07   ` Xing, Beilei
2021-01-06  7:43     ` Xia, Chenbo
2020-12-18  9:37 ` [dpdk-dev] [PATCH 0/9] Introduce vfio-user library David Marchand
2020-12-18 14:07   ` Thanos Makatos
2023-06-29 16:10     ` Stephen Hemminger
2023-06-30  1:36       ` Xia, Chenbo
2021-01-14  6:14 ` [dpdk-dev] [PATCH v2 " Chenbo Xia
2021-01-14  6:14   ` [dpdk-dev] [PATCH v2 1/9] lib: introduce " Chenbo Xia
2024-02-12 22:53     ` Stephen Hemminger
2021-01-14  6:14   ` [dpdk-dev] [PATCH v2 2/9] vfio_user: implement lifecycle related APIs Chenbo Xia
2021-01-14  6:14   ` [dpdk-dev] [PATCH v2 3/9] vfio_user: implement device and region " Chenbo Xia
2021-01-14 18:48     ` David Christensen
2021-01-19  3:22       ` Xia, Chenbo
2021-01-14  6:14   ` [dpdk-dev] [PATCH v2 4/9] vfio_user: implement DMA table and socket address API Chenbo Xia
2021-01-14  6:14   ` [dpdk-dev] [PATCH v2 5/9] vfio_user: implement interrupt related APIs Chenbo Xia
2021-01-14  6:14   ` [dpdk-dev] [PATCH v2 6/9] vfio_user: add client APIs of device attach/detach Chenbo Xia
2021-01-14  6:14   ` [dpdk-dev] [PATCH v2 7/9] vfio_user: add client APIs of DMA/IRQ/region Chenbo Xia
2021-01-14  6:14   ` [dpdk-dev] [PATCH v2 8/9] test/vfio_user: introduce functional test Chenbo Xia
2021-01-14 19:03     ` David Christensen
2021-01-19  3:27       ` Xia, Chenbo
2021-01-19 18:26         ` David Christensen
2021-01-14  6:14   ` [dpdk-dev] [PATCH v2 9/9] doc: add vfio-user library guide Chenbo Xia
2021-01-15  7:58   ` [dpdk-dev] [PATCH v2 0/9] Introduce vfio-user library David Marchand
2021-01-19  3:13     ` 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=20201218073851.93609-9-chenbo.xia@intel.com \
    --to=chenbo.xia@intel.com \
    --cc=cunming.liang@intel.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=jingjing.wu@intel.com \
    --cc=miao.li@intel.com \
    --cc=stephen@networkplumber.org \
    --cc=thomas@monjalon.net \
    --cc=xiuchun.lu@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.