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,
beilei.xing@intel.com
Subject: [dpdk-dev] [PATCH v2 8/9] test/vfio_user: introduce functional test
Date: Thu, 14 Jan 2021 14:14:10 +0800 [thread overview]
Message-ID: <20210114061411.39166-9-chenbo.xia@intel.com> (raw)
In-Reply-To: <20210114061411.39166-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 | 665 ++++++++++++++++++++++++++++++++++++++
2 files changed, 669 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..c5fc0e842c
--- /dev/null
+++ b/app/test/test_vfio_user.c
@@ -0,0 +1,665 @@
+/* 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_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_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_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, ®_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 allocate 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
next prev parent reply other threads:[~2021-01-14 6:20 UTC|newest]
Thread overview: 45+ 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 ` [dpdk-dev] [PATCH 8/9] test/vfio_user: introduce functional test Chenbo Xia
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
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 ` Chenbo Xia [this message]
2021-01-14 19:03 ` [dpdk-dev] [PATCH v2 8/9] test/vfio_user: introduce functional test 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=20210114061411.39166-9-chenbo.xia@intel.com \
--to=chenbo.xia@intel.com \
--cc=beilei.xing@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 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).