aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohn Levon <john.levon@nutanix.com>2020-11-25 16:39:41 +0000
committerGitHub <noreply@github.com>2020-11-25 16:39:41 +0000
commit48c55b26a05ab8d4bf7afdfed98bd8a71142848f (patch)
tree071c1766d0816577fa0c948cfb0bba84c7057855 /lib
parent384c1c80d4ddc397684704c85441183bfecd5d13 (diff)
downloadlibvfio-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>
Diffstat (limited to 'lib')
-rw-r--r--lib/muser_ctx.c38
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,