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 7/9] vfio_user: add client APIs of DMA/IRQ/region Date: Fri, 18 Dec 2020 15:38:49 +0800 Message-ID: <20201218073851.93609-8-chenbo.xia@intel.com> (raw) In-Reply-To: <20201218073851.93609-1-chenbo.xia@intel.com> This patch introduces nine APIs - Device related: rte_vfio_user_get_dev_info and rte_vfio_user_reset - DMA related: rte_vfio_user_dma_map/unmap - Region related: rte_vfio_user_get_reg_info and rte_vfio_user_region_read/write - IRQ related: rte_vfio_user_get_irq_info and rte_vfio_user_set_irqs 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 | 168 ++++++++++ lib/librte_vfio_user/version.map | 9 + lib/librte_vfio_user/vfio_user_client.c | 412 ++++++++++++++++++++++++ 3 files changed, 589 insertions(+) diff --git a/lib/librte_vfio_user/rte_vfio_user.h b/lib/librte_vfio_user/rte_vfio_user.h index b09d83e224..fe27d05992 100644 --- a/lib/librte_vfio_user/rte_vfio_user.h +++ b/lib/librte_vfio_user/rte_vfio_user.h @@ -229,6 +229,15 @@ int rte_vfio_user_set_irq_info(const char *sock_addr, * Below APIs are for vfio-user client (device consumer) to use: * *rte_vfio_user_attach_dev * *rte_vfio_user_detach_dev + * *rte_vfio_user_get_dev_info + * *rte_vfio_user_get_reg_info + * *rte_vfio_user_get_irq_info + * *rte_vfio_user_dma_map + * *rte_vfio_user_dma_unmap + * *rte_vfio_user_set_irqs + * *rte_vfio_user_region_read + * *rte_vfio_user_region_write + * *rte_vfio_user_reset */ /** @@ -255,4 +264,163 @@ int rte_vfio_user_attach_dev(const char *sock_addr); __rte_experimental int rte_vfio_user_detach_dev(int dev_id); +/** + * Get device information of a vfio-user device. + * + * @param dev_id + * Device ID of the vfio-user device + * @param[out] info + * A pointer to a structure of type *vfio_device_info* to be filled with the + * information of the device. + * @return + * - 0: Success, device information updated + * - <0: Failure on get device information + */ +__rte_experimental +int rte_vfio_user_get_dev_info(int dev_id, struct vfio_device_info *info); + +/** + * Get region information of a vfio-user device. + * + * @param dev_id + * Device ID of the vfio-user device + * @param[out] info + * A pointer to a structure of type *vfio_region_info* to be filled with the + * information of the device region. + * @param[out] fd + * A pointer to the file descriptor of the region + * @return + * - 0: Success, region information and file descriptor updated. If the region + * can not be mmaped, the file descriptor should be -1. + * - <0: Failure on get region information + */ +__rte_experimental +int rte_vfio_user_get_reg_info(int dev_id, struct vfio_region_info *info, + int *fd); + +/** + * Get IRQ information of a vfio-user device. + * + * @param dev_id + * Device ID of the vfio-user device + * @param[out] info + * A pointer to a structure of type *vfio_irq_info* to be filled with the + * information of the IRQ. + * @return + * - 0: Success, IRQ information updated + * - <0: Failure on get IRQ information + */ +__rte_experimental +int rte_vfio_user_get_irq_info(int dev_id, struct vfio_irq_info *info); + +/** + * Map DMA regions for the vfio-user device. + * + * @param dev_id + * Device ID of the vfio-user device + * @param mem + * A pointer to a structure of type *vfio_user_mem_reg* that identifies + * one or several DMA regions. + * @param fds + * A pointer to a list of file descriptors. One file descriptor maps to + * one DMA region. + * @param num + * Number of DMA regions (or file descriptors) + * @return + * - 0: Success, all DMA regions are mapped. + * - <0: Failure on DMA map. It should be assumed that all DMA regions + * are not mapped. + */ +__rte_experimental +int rte_vfio_user_dma_map(int dev_id, struct rte_vfio_user_mem_reg *mem, + int *fds, uint32_t num); + +/** + * Unmap DMA regions for the vfio-user device. + * + * @param dev_id + * Device ID of the vfio-user device + * @param mem + * A pointer to a structure of type *vfio_user_mem_reg* that identifies + * one or several DMA regions. + * @param num + * Number of DMA regions + * @return + * - 0: Success, all DMA regions are unmapped. + * - <0: Failure on DMA unmap. It should be assumed that all DMA regions + * are not unmapped. + */ +__rte_experimental +int rte_vfio_user_dma_unmap(int dev_id, struct rte_vfio_user_mem_reg *mem, + uint32_t num); + +/** + * Set interrupt signaling, masking, and unmasking for the vfio-user device. + * + * @param dev_id + * Device ID of the vfio-user device + * @param set + * A pointer to a structure of type *vfio_irq_set* that specifies the set + * data and action + * @return + * - 0: Success, IRQs are set successfully. + * - <0: Failure on IRQ set. + */ +__rte_experimental +int rte_vfio_user_set_irqs(int dev_id, struct vfio_irq_set *set); + +/** + * Read region of the vfio-user device. + * + * @param dev_id + * Device ID of the vfio-user device + * @param idx + * The region index + * @param offset + * The region offset + * @param size + * Size of the read data + * @param[out] data + * The pointer to data to be filled with correct region data + * @return + * - 0: Success on region read + * - <0: Failure on region read + */ +__rte_experimental +int rte_vfio_user_region_read(int dev_id, uint32_t idx, uint64_t offset, + uint32_t size, void *data); + +/** + * Write region of the vfio-user device. + * + * @param dev_id + * Device ID of the vfio-user device + * @param idx + * The region index + * @param offset + * The region offset + * @param size + * Size of the read data + * @param data + * The pointer to data that will be written to the region + * @return + * - 0: Success on region write + * - <0: Failure on region write + */ +__rte_experimental +int rte_vfio_user_region_write(int dev_id, uint32_t idx, uint64_t offset, + uint32_t size, const void *data); + +/** + * Reset the vfio-user device + * + * @param dev_id + * Device ID of the vfio-user device + * @return + * - 0: Success on device reset + * - <0: Failure on device reset + */ +__rte_experimental +int rte_vfio_user_reset(int dev_id); + #endif diff --git a/lib/librte_vfio_user/version.map b/lib/librte_vfio_user/version.map index a0cda2b49c..2e362d00bc 100644 --- a/lib/librte_vfio_user/version.map +++ b/lib/librte_vfio_user/version.map @@ -12,6 +12,15 @@ EXPERIMENTAL { rte_vfio_user_set_irq_info; rte_vfio_user_attach_dev; rte_vfio_user_detach_dev; + rte_vfio_user_get_dev_info; + rte_vfio_user_get_reg_info; + rte_vfio_user_get_irq_info; + rte_vfio_user_dma_map; + rte_vfio_user_dma_unmap; + rte_vfio_user_set_irqs; + rte_vfio_user_region_read; + rte_vfio_user_region_write; + rte_vfio_user_reset; local: *; }; diff --git a/lib/librte_vfio_user/vfio_user_client.c b/lib/librte_vfio_user/vfio_user_client.c index 85b2e8cb46..24969563d5 100644 --- a/lib/librte_vfio_user/vfio_user_client.c +++ b/lib/librte_vfio_user/vfio_user_client.c @@ -277,3 +277,415 @@ int rte_vfio_user_detach_dev(int dev_id) return ret; } + +int rte_vfio_user_get_dev_info(int dev_id, struct vfio_device_info *info) +{ + VFIO_USER_MSG msg; + struct vfio_user_client *dev; + int ret; + uint32_t sz = VFIO_USER_MSG_HDR_SIZE + sizeof(struct vfio_device_info); + + if (!info) + return -EINVAL; + + dev = vfio_client_devs.cl[dev_id]; + if (!dev) { + VFIO_USER_LOG(ERR, "Failed to get device info: " + "wrong device ID\n"); + return -EINVAL; + } + + memset(&msg, 0, sizeof(VFIO_USER_MSG)); + vfio_user_client_fill_hdr(&msg, VFIO_USER_DEVICE_GET_INFO, sz); + + ret = vfio_user_client_send_recv(dev->sock.sock_fd, &msg); + if (ret) + return ret; + + if (msg.flags & VFIO_USER_ERROR) { + VFIO_USER_LOG(ERR, "Failed to get device info: %s\n", + msg.err ? strerror(msg.err) : "Unknown error"); + return msg.err ? -(int)msg.err : -1; + } + + if (vfio_user_check_msg_fdnum(&msg, 0) != 0) + return -1; + + memcpy(info, &msg.payload.dev_info, sizeof(*info)); + return ret; +} + +int rte_vfio_user_get_reg_info(int dev_id, struct vfio_region_info *info, + int *fd) +{ + VFIO_USER_MSG msg; + int ret, fd_num = 0; + struct vfio_user_client *dev; + uint32_t sz = VFIO_USER_MSG_HDR_SIZE + info->argsz; + struct vfio_user_reg *reg = &msg.payload.reg_info; + + if (!info || !fd) + return -EINVAL; + + dev = vfio_client_devs.cl[dev_id]; + if (!dev) { + VFIO_USER_LOG(ERR, "Failed to get region info: " + "wrong device ID\n"); + return -EINVAL; + } + + memset(&msg, 0, sizeof(VFIO_USER_MSG)); + vfio_user_client_fill_hdr(&msg, VFIO_USER_DEVICE_GET_REGION_INFO, sz); + reg->reg_info.index = info->index; + + ret = vfio_user_client_send_recv(dev->sock.sock_fd, &msg); + if (ret) + return ret; + + if (msg.flags & VFIO_USER_ERROR) { + VFIO_USER_LOG(ERR, "Failed to get region(%u) info: %s\n", + info->index, msg.err ? strerror(msg.err) : + "Unknown error"); + return msg.err ? -(int)msg.err : -1; + } + + if (reg->reg_info.flags & VFIO_REGION_INFO_FLAG_MMAP) + fd_num = 1; + + if (vfio_user_check_msg_fdnum(&msg, fd_num) != 0) + return -1; + + if (reg->reg_info.index != info->index || + msg.size - VFIO_USER_MSG_HDR_SIZE > sizeof(*reg)) { + VFIO_USER_LOG(ERR, + "Incorrect reply message for region info\n"); + return -1; + } + + memcpy(info, &msg.payload.reg_info, info->argsz); + *fd = fd_num == 1 ? msg.fds[0] : -1; + + return 0; +} + +int rte_vfio_user_get_irq_info(int dev_id, struct vfio_irq_info *info) +{ + VFIO_USER_MSG msg; + int ret; + struct vfio_user_client *dev; + uint32_t sz = VFIO_USER_MSG_HDR_SIZE + sizeof(struct vfio_irq_info); + struct vfio_irq_info *irq_info = &msg.payload.irq_info; + + if (!info) + return -EINVAL; + + dev = vfio_client_devs.cl[dev_id]; + if (!dev) { + VFIO_USER_LOG(ERR, "Failed to get region info: " + "wrong device ID\n"); + return -EINVAL; + } + + memset(&msg, 0, sizeof(VFIO_USER_MSG)); + vfio_user_client_fill_hdr(&msg, VFIO_USER_DEVICE_GET_IRQ_INFO, sz); + irq_info->index = info->index; + + ret = vfio_user_client_send_recv(dev->sock.sock_fd, &msg); + if (ret) + return ret; + + if (msg.flags & VFIO_USER_ERROR) { + VFIO_USER_LOG(ERR, "Failed to get irq(%u) info: %s\n", + info->index, msg.err ? strerror(msg.err) : + "Unknown error"); + return msg.err ? -(int)msg.err : -1; + } + + if (vfio_user_check_msg_fdnum(&msg, 0) != 0) + return -1; + + if (irq_info->index != info->index || + msg.size - VFIO_USER_MSG_HDR_SIZE != sizeof(*irq_info)) { + VFIO_USER_LOG(ERR, + "Incorrect reply message for IRQ info\n"); + return -1; + } + + memcpy(info, irq_info, sizeof(*info)); + return 0; +} + +static int vfio_user_client_dma_map_unmap(struct vfio_user_client *dev, + struct rte_vfio_user_mem_reg *mem, int *fds, uint32_t num, bool ismap) +{ + VFIO_USER_MSG msg; + int ret; + uint32_t i, mem_sz, map; + uint16_t cmd = VFIO_USER_DMA_UNMAP; + + memset(&msg, 0, sizeof(VFIO_USER_MSG)); + + if (num > VFIO_USER_MSG_MAX_NREG) { + VFIO_USER_LOG(ERR, + "Too many memory regions to %s (MAX: %u)\n", + ismap ? "map" : "unmap", VFIO_USER_MSG_MAX_NREG); + return -EINVAL; + } + + if (ismap) { + cmd = VFIO_USER_DMA_MAP; + + for (i = 0; i < num; i++) { + map = mem->flags & RTE_VUSER_MEM_MAPPABLE; + if ((map && (fds[i] == -1)) || + (!map && (fds[i] != -1))) { + VFIO_USER_LOG(ERR, "%spable memory region " + "should%s have valid fd\n", + ismap ? "Map" : "Unmap", + ismap ? "" : " not"); + return -EINVAL; + } + + if (fds[i] != -1) + msg.fds[msg.fd_num++] = fds[i]; + } + } + + mem_sz = sizeof(struct rte_vfio_user_mem_reg) * num; + memcpy(&msg.payload, mem, mem_sz); + + vfio_user_client_fill_hdr(&msg, cmd, mem_sz + VFIO_USER_MSG_HDR_SIZE); + + ret = vfio_user_client_send_recv(dev->sock.sock_fd, &msg); + if (ret) + return ret; + + if (msg.flags & VFIO_USER_ERROR) { + VFIO_USER_LOG(ERR, "Failed to %smap memory regions: " + "%s\n", ismap ? "" : "un", + msg.err ? strerror(msg.err) : "Unknown error"); + return msg.err ? -(int)msg.err : -1; + } + + if (vfio_user_check_msg_fdnum(&msg, 0) != 0) + return -1; + + return 0; +} + +int rte_vfio_user_dma_map(int dev_id, struct rte_vfio_user_mem_reg *mem, + int *fds, uint32_t num) +{ + struct vfio_user_client *dev; + + if (!mem || !fds) + return -EINVAL; + + dev = vfio_client_devs.cl[dev_id]; + if (!dev) { + VFIO_USER_LOG(ERR, "Failed to dma map: " + "wrong device ID\n"); + return -EINVAL; + } + + return vfio_user_client_dma_map_unmap(dev, mem, fds, num, true); +} + +int rte_vfio_user_dma_unmap(int dev_id, struct rte_vfio_user_mem_reg *mem, + uint32_t num) +{ + struct vfio_user_client *dev; + + if (!mem) + return -EINVAL; + + dev = vfio_client_devs.cl[dev_id]; + if (!dev) { + VFIO_USER_LOG(ERR, "Failed to dma unmap: " + "wrong device ID\n"); + return -EINVAL; + } + + return vfio_user_client_dma_map_unmap(dev, mem, NULL, num, false); +} + +int rte_vfio_user_set_irqs(int dev_id, struct vfio_irq_set *set) +{ + VFIO_USER_MSG msg; + int ret; + struct vfio_user_client *dev; + uint32_t set_sz = set->argsz; + struct vfio_user_irq_set *irq_set = &msg.payload.irq_set; + + if (!set) + return -EINVAL; + + dev = vfio_client_devs.cl[dev_id]; + if (!dev) { + VFIO_USER_LOG(ERR, "Failed to set irqs: " + "wrong device ID\n"); + return -EINVAL; + } + + memset(&msg, 0, sizeof(VFIO_USER_MSG)); + + if (set->flags & VFIO_IRQ_SET_DATA_EVENTFD) { + msg.fd_num = set->count; + memcpy(msg.fds, set->data, sizeof(int) * set->count); + set_sz -= sizeof(int) * set->count; + } + memcpy(irq_set, set, set_sz); + irq_set->set.argsz = set_sz; + vfio_user_client_fill_hdr(&msg, VFIO_USER_DEVICE_SET_IRQS, + VFIO_USER_MSG_HDR_SIZE + set_sz); + + ret = vfio_user_client_send_recv(dev->sock.sock_fd, &msg); + if (ret) + return ret; + + if (msg.flags & VFIO_USER_ERROR) { + VFIO_USER_LOG(ERR, "Failed to set irq(%u): %s\n", + set->index, msg.err ? strerror(msg.err) : + "Unknown error"); + return msg.err ? -(int)msg.err : -1; + } + + if (vfio_user_check_msg_fdnum(&msg, 0) != 0) + return -1; + + return 0; +} + +int rte_vfio_user_region_read(int dev_id, uint32_t idx, uint64_t offset, + uint32_t size, void *data) +{ + VFIO_USER_MSG msg; + int ret; + struct vfio_user_client *dev; + uint32_t sz = VFIO_USER_MSG_HDR_SIZE + sizeof(struct vfio_user_reg_rw) + - VFIO_USER_MAX_RW_DATA; + struct vfio_user_reg_rw *rw = &msg.payload.reg_rw; + + if (!data) + return -EINVAL; + + dev = vfio_client_devs.cl[dev_id]; + if (!dev) { + VFIO_USER_LOG(ERR, "Failed to read region: " + "wrong device ID\n"); + return -EINVAL; + } + + if (sz > VFIO_USER_MAX_RW_DATA) { + VFIO_USER_LOG(ERR, "Region read size exceeds max\n"); + return -1; + } + + memset(&msg, 0, sizeof(VFIO_USER_MSG)); + vfio_user_client_fill_hdr(&msg, VFIO_USER_REGION_READ, sz); + + rw->reg_idx = idx; + rw->reg_offset = offset; + rw->size = size; + + ret = vfio_user_client_send_recv(dev->sock.sock_fd, &msg); + if (ret) + return ret; + + if (msg.flags & VFIO_USER_ERROR) { + VFIO_USER_LOG(ERR, "Failed to read region(%u): %s\n", + idx, msg.err ? strerror(msg.err) : + "Unknown error"); + return msg.err ? -(int)msg.err : -1; + } + + if (vfio_user_check_msg_fdnum(&msg, 0) != 0) + return -1; + + memcpy(data, rw->data, size); + return 0; +} + +int rte_vfio_user_region_write(int dev_id, uint32_t idx, uint64_t offset, + uint32_t size, const void *data) +{ + VFIO_USER_MSG msg; + int ret; + struct vfio_user_client *dev; + uint32_t sz = VFIO_USER_MSG_HDR_SIZE + sizeof(struct vfio_user_reg_rw) + - VFIO_USER_MAX_RW_DATA + size; + struct vfio_user_reg_rw *rw = &msg.payload.reg_rw; + + if (!data) + return -EINVAL; + + dev = vfio_client_devs.cl[dev_id]; + if (!dev) { + VFIO_USER_LOG(ERR, "Failed to write region: " + "wrong device ID\n"); + return -EINVAL; + } + + if (sz > VFIO_USER_MAX_RW_DATA) { + VFIO_USER_LOG(ERR, "Region write size exceeds max\n"); + return -EINVAL; + } + + memset(&msg, 0, sizeof(VFIO_USER_MSG)); + vfio_user_client_fill_hdr(&msg, VFIO_USER_REGION_WRITE, sz); + + rw->reg_idx = idx; + rw->reg_offset = offset; + rw->size = size; + memcpy(rw->data, data, size); + + ret = vfio_user_client_send_recv(dev->sock.sock_fd, &msg); + if (ret) + return ret; + + if (msg.flags & VFIO_USER_ERROR) { + VFIO_USER_LOG(ERR, "Failed to write region(%u): %s\n", + idx, msg.err ? strerror(msg.err) : + "Unknown error"); + return msg.err ? -(int)msg.err : -1; + } + + if (vfio_user_check_msg_fdnum(&msg, 0) != 0) + return -1; + + return 0; +} + +int rte_vfio_user_reset(int dev_id) +{ + VFIO_USER_MSG msg; + int ret; + struct vfio_user_client *dev; + uint32_t sz = VFIO_USER_MSG_HDR_SIZE; + + dev = vfio_client_devs.cl[dev_id]; + if (!dev) { + VFIO_USER_LOG(ERR, "Failed to write region: " + "wrong device ID\n"); + return -EINVAL; + } + + memset(&msg, 0, sizeof(VFIO_USER_MSG)); + vfio_user_client_fill_hdr(&msg, VFIO_USER_DEVICE_RESET, sz); + + ret = vfio_user_client_send_recv(dev->sock.sock_fd, &msg); + if (ret) + return ret; + + if (msg.flags & VFIO_USER_ERROR) { + VFIO_USER_LOG(ERR, "Failed to reset device: %s\n", + msg.err ? strerror(msg.err) : + "Unknown error"); + return msg.err ? -(int)msg.err : -1; + } + + if (vfio_user_check_msg_fdnum(&msg, 0) != 0) + return -1; + + return ret; +} -- 2.17.1
next prev parent reply other threads:[~2020-12-18 7:56 UTC|newest] Thread overview: 43+ 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 ` Chenbo Xia [this message] 2021-01-07 2:41 ` [dpdk-dev] [PATCH 7/9] vfio_user: add client APIs of DMA/IRQ/region 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 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 ` [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-8-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
DPDK patches and discussions This inbox may be cloned and mirrored by anyone: git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \ dev@dpdk.org public-inbox-index dev Example config snippet for mirrors. Newsgroup available over NNTP: nntp://inbox.dpdk.org/inbox.dpdk.dev AGPL code for this site: git clone https://public-inbox.org/public-inbox.git