aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThanos Makatos <thanos.makatos@nutanix.com>2020-12-01 07:37:07 -0500
committerThanos <tmakatos@gmail.com>2020-12-01 15:41:25 +0000
commit50f21d54d5ea96703afb466a2d2a7c805aba3f59 (patch)
treee77238fa3e5b7757da6896262ca58bd100a007bb /lib
parente68ae954776a048838be74f0bc049205acfeb878 (diff)
downloadlibvfio-user-50f21d54d5ea96703afb466a2d2a7c805aba3f59.zip
libvfio-user-50f21d54d5ea96703afb466a2d2a7c805aba3f59.tar.gz
libvfio-user-50f21d54d5ea96703afb466a2d2a7c805aba3f59.tar.bz2
make consume_fd to return the fd it consumes
Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/irq.c8
-rw-r--r--lib/libvfio-user.c30
-rw-r--r--lib/private.h4
3 files changed, 30 insertions, 12 deletions
diff --git a/lib/irq.c b/lib/irq.c
index e5c0b6d..9a4beff 100644
--- a/lib/irq.c
+++ b/lib/irq.c
@@ -171,9 +171,13 @@ irqs_set_data_eventfd(vfu_ctx_t *vfu_ctx, struct vfio_irq_set *irq_set,
vfu_ctx->irqs->efds[i] = -1;
}
- if (data[j] >= 0) {
+ if (data[j] >= 0) { /* TODO IIUC this will always be >= 0? */
vfu_ctx->irqs->efds[i] = data[j];
- consume_fd(data, j);
+ /*
+ * We've already checked in handle_device_set_irqs that
+ * nr_fds == irq_set->count.
+ */
+ consume_fd(data, irq_set->count, j);
}
vfu_log(vfu_ctx, VFU_DBG, "event fd[%d]=%d", i, vfu_ctx->irqs->efds[i]);
}
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index a930258..e0b8465 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -500,10 +500,24 @@ handle_device_get_info(vfu_ctx_t *vfu_ctx, uint32_t size,
return 0;
}
+int
+consume_fd(int *fds, size_t nr_fds, size_t index)
+{
+ int fd;
+
+ if (index >= nr_fds) {
+ return -EINVAL;
+ }
+
+ fd = fds[index];
+ fds[index] = -1;
+ return fd;
+}
+
void
-consume_fd(int *fds, size_t index)
+restore_fd(int *fds, size_t index, int fd)
{
- fds[index] = -1;
+ fds[index] = fd;
}
/*
@@ -549,11 +563,11 @@ handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
if (map) {
int fd = -1;
if (dma_regions[i].flags == VFIO_USER_F_DMA_REGION_MAPPABLE) {
- if (fdi == nr_fds) {
- ret = -EINVAL;
+ fd = consume_fd(fds, nr_fds, fdi++);
+ if (fd < 0) {
+ ret = fd;
break;
}
- fd = fds[fdi];
}
ret = dma_controller_add_region(vfu_ctx->dma,
@@ -562,6 +576,9 @@ handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
fd,
dma_regions[i].offset);
if (ret < 0) {
+ if (fd != -1) {
+ restore_fd(fds, fdi - 1, fd);
+ }
vfu_log(vfu_ctx, VFU_INF,
"failed to add DMA region %#lx-%#lx offset=%#lx fd=%d: %s",
dma_regions[i].addr,
@@ -570,9 +587,6 @@ handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
strerror(-ret));
break;
}
- if (dma_regions[i].flags == VFIO_USER_F_DMA_REGION_MAPPABLE) {
- consume_fd(fds, fdi++);
- }
vfu_log(vfu_ctx, VFU_DBG,
"added DMA region %#lx-%#lx offset=%#lx fd=%d",
dma_regions[i].addr,
diff --git a/lib/private.h b/lib/private.h
index 2753a20..a2fb3a7 100644
--- a/lib/private.h
+++ b/lib/private.h
@@ -163,8 +163,8 @@ exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size,
int
process_request(vfu_ctx_t *vfu_ctx);
-void
-consume_fd(int *fds, size_t index);
+int
+consume_fd(int *fds, size_t nr_fds, size_t index);
#endif /* LIB_VFIO_USER_PRIVATE_H */