From 45aaf0db1d6589c3cf195dc575d5defd2db76396 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Wed, 24 Mar 2021 20:30:22 +0800 Subject: [PATCH] nvmf/vfio-user: register external DMA memory regions to SPDK For NVMe backend device, we should use vtophys to calculate physical address when doing DMA from/to VM to drives. Fix #1822. Change-Id: Ib8fbc371e19e77a20202d408340e7d65644b1eeb Signed-off-by: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7261 Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/nvmf/vfio_user.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/nvmf/vfio_user.c b/lib/nvmf/vfio_user.c index 980954f0d..f3a5ab7b2 100644 --- a/lib/nvmf/vfio_user.c +++ b/lib/nvmf/vfio_user.c @@ -1091,6 +1091,16 @@ memory_region_add_cb(vfu_ctx_t *vfu_ctx, vfu_dma_info_t *info) (uintptr_t)info->mapping.iov_base, (uintptr_t)info->mapping.iov_base + info->mapping.iov_len); + /* VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE are enabled when registering to VFIO, here we also + * check the protection bits before registering. + */ + if ((info->prot == (PROT_WRITE | PROT_READ)) && + (spdk_mem_register(info->mapping.iov_base, info->mapping.iov_len))) { + SPDK_ERRLOG("Memory region register %#lx-%#lx failed\n", + (uint64_t)(uintptr_t)info->mapping.iov_base, + (uint64_t)(uintptr_t)info->mapping.iov_base + info->mapping.iov_len); + } + for (i = 0; i < NVMF_VFIO_USER_DEFAULT_MAX_QPAIRS_PER_CTRLR; i++) { qpair = ctrlr->qp[i]; if (qpair == NULL) { @@ -1157,6 +1167,13 @@ memory_region_remove_cb(vfu_ctx_t *vfu_ctx, vfu_dma_info_t *info) (uintptr_t)info->mapping.iov_base, (uintptr_t)info->mapping.iov_base + info->mapping.iov_len); + if ((info->prot == (PROT_WRITE | PROT_READ)) && + (spdk_mem_unregister(info->mapping.iov_base, info->mapping.iov_len))) { + SPDK_ERRLOG("Memory region unregister %#lx-%#lx failed\n", + (uint64_t)(uintptr_t)info->mapping.iov_base, + (uint64_t)(uintptr_t)info->mapping.iov_base + info->mapping.iov_len); + } + map_start = info->mapping.iov_base; map_end = info->mapping.iov_base + info->mapping.iov_len; for (i = 0; i < NVMF_VFIO_USER_DEFAULT_MAX_QPAIRS_PER_CTRLR; i++) {