diff options
author | John Levon <john.levon@nutanix.com> | 2020-11-25 16:39:41 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-25 16:39:41 +0000 |
commit | 48c55b26a05ab8d4bf7afdfed98bd8a71142848f (patch) | |
tree | 071c1766d0816577fa0c948cfb0bba84c7057855 | |
parent | 384c1c80d4ddc397684704c85441183bfecd5d13 (diff) | |
download | libvfio-user-48c55b26a05ab8d4bf7afdfed98bd8a71142848f.zip libvfio-user-48c55b26a05ab8d4bf7afdfed98bd8a71142848f.tar.gz libvfio-user-48c55b26a05ab8d4bf7afdfed98bd8a71142848f.tar.bz2 |
handle_dma_map_or_unmap(): correct fd handling (#118)
We shouldn't consume fd's for regions lacking VFIO_USER_F_DMA_REGION_MAPPABLE.
In addition, we'll ignore such a region (this is a temporary hack).
Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Signed-off-by: John Levon <john.levon@nutanix.com>
-rw-r--r-- | lib/muser_ctx.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/lib/muser_ctx.c b/lib/muser_ctx.c index 6f01d41..e1b18b1 100644 --- a/lib/muser_ctx.c +++ b/lib/muser_ctx.c @@ -504,8 +504,9 @@ handle_dma_map_or_unmap(lm_ctx_t *lm_ctx, uint32_t size, bool map, int *fds, int nr_fds, struct vfio_user_dma_region *dma_regions) { - int ret, i; int nr_dma_regions; + int fdi = 0; + int ret, i; assert(lm_ctx != NULL); @@ -519,40 +520,49 @@ handle_dma_map_or_unmap(lm_ctx_t *lm_ctx, uint32_t size, bool map, } nr_dma_regions = (int)(size / sizeof(struct vfio_user_dma_region)); - if (map && nr_dma_regions != nr_fds) { - lm_log(lm_ctx, LM_ERR, "expected %d fds but got %d instead", - nr_dma_regions, nr_fds); - return -EINVAL; - } for (i = 0; i < nr_dma_regions; i++) { if (map) { + int fd; + + /* + * FIXME: need a dma controller that allows non-fd region. + */ if (dma_regions[i].flags != VFIO_USER_F_DMA_REGION_MAPPABLE) { - /* - * FIXME implement non-mappable DMA regions. This requires changing - * dma.c to not take a file descriptor. - */ - assert(false); + lm_log(lm_ctx, LM_INF, + "FIXME: ignored non-mappable DMA region " + "%#lx-%#lx offset=%#lx", + dma_regions[i].addr, + dma_regions[i].addr + dma_regions[i].size - 1, + dma_regions[i].offset); + continue; } + if (fdi >= nr_fds) { + lm_log(lm_ctx, LM_ERR, "missing fd for mappable region %d", i); + return -EINVAL; + } + + fd = fds[fdi++]; + ret = dma_controller_add_region(lm_ctx->dma, dma_regions[i].addr, dma_regions[i].size, - fds[i], + fd, dma_regions[i].offset); if (ret < 0) { lm_log(lm_ctx, LM_INF, "failed to add DMA region %#lx-%#lx offset=%#lx fd=%d: %s", dma_regions[i].addr, dma_regions[i].addr + dma_regions[i].size - 1, - dma_regions[i].offset, fds[i], + dma_regions[i].offset, fd, strerror(-ret)); } else { lm_log(lm_ctx, LM_DBG, "added DMA region %#lx-%#lx offset=%#lx fd=%d", dma_regions[i].addr, dma_regions[i].addr + dma_regions[i].size - 1, - dma_regions[i].offset, fds[i]); + dma_regions[i].offset, fd); } } else { ret = dma_controller_remove_region(lm_ctx->dma, |