aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThanos Makatos <thanos.makatos@nutanix.com>2020-11-26 05:37:34 -0500
committerThanos <tmakatos@gmail.com>2020-11-27 09:36:12 +0000
commit7df3de2f9d2a8fcfd6bb24ddbfc5aa20e237f464 (patch)
tree821f8cfbbe2ac9906dfa2780e2feab164ba97937 /lib
parent24cacccd92a0da049af83d4da35bd3bcebf236ae (diff)
downloadlibvfio-user-7df3de2f9d2a8fcfd6bb24ddbfc5aa20e237f464.zip
libvfio-user-7df3de2f9d2a8fcfd6bb24ddbfc5aa20e237f464.tar.gz
libvfio-user-7df3de2f9d2a8fcfd6bb24ddbfc5aa20e237f464.tar.bz2
add unit tests for DMA regions without file descriptor
Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/common.h3
-rw-r--r--lib/dma.c15
-rw-r--r--lib/muser_ctx.c24
-rw-r--r--lib/muser_priv.h4
4 files changed, 29 insertions, 17 deletions
diff --git a/lib/common.h b/lib/common.h
index e30bc2e..dbd3c9b 100644
--- a/lib/common.h
+++ b/lib/common.h
@@ -55,6 +55,9 @@
#define ROUND_DOWN(x, a) ((x) & ~((a)-1))
#define ROUND_UP(x,a) ROUND_DOWN((x)+(a)-1, a)
+#define UNIT_TEST_SYMBOL(x) \
+ typeof(x) __wrap_##x __attribute__((weak, alias(#x)))
+
#endif /* LIB_MUSER_COMMON_H */
/* ex: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/lib/dma.c b/lib/dma.c
index b47652d..bcc6128 100644
--- a/lib/dma.c
+++ b/lib/dma.c
@@ -90,7 +90,7 @@ dma_controller_create(lm_ctx_t *lm_ctx, int max_regions)
return dma;
}
-static void
+void
_dma_controller_do_remove_region(dma_controller_t *dma,
dma_memory_region_t *region)
{
@@ -111,6 +111,14 @@ _dma_controller_do_remove_region(dma_controller_t *dma,
}
}
}
+UNIT_TEST_SYMBOL(_dma_controller_do_remove_region);
+
+/*
+ * FIXME super ugly, but without this functions within the same compilation
+ * unit don't call the wrapped version, making unit testing impossible.
+ * Ideally we'd like the UNIT_TEST_SYMBOL macro to solve this.
+ */
+#define _dma_controller_do_remove_region __wrap__dma_controller_do_remove_region
/*
* FIXME no longer used. Also, it doesn't work for addresses that span two
@@ -173,6 +181,7 @@ dma_controller_remove_region(dma_controller_t *dma,
}
return -ENOENT;
}
+UNIT_TEST_SYMBOL(dma_controller_remove_region);
static inline void
dma_controller_remove_regions(dma_controller_t *dma)
@@ -292,6 +301,8 @@ dma_controller_add_region(dma_controller_t *dma,
}
goto err;
}
+ } else {
+ region->virt_addr = NULL;
}
dma->nregions++;
@@ -300,6 +311,7 @@ dma_controller_add_region(dma_controller_t *dma,
err:
return -idx - 1;
}
+UNIT_TEST_SYMBOL(dma_controller_add_region);
static inline void
mmap_round(size_t *offset, size_t *size, size_t page_size)
@@ -334,6 +346,7 @@ dma_map_region(dma_memory_region_t *region, int prot, size_t offset, size_t len)
return mmap_base + (offset - mmap_offset);
}
+UNIT_TEST_SYMBOL(dma_map_region);
int
dma_unmap_region(dma_memory_region_t *region, void *virt_addr, size_t len)
diff --git a/lib/muser_ctx.c b/lib/muser_ctx.c
index e00a55a..d80e952 100644
--- a/lib/muser_ctx.c
+++ b/lib/muser_ctx.c
@@ -519,7 +519,7 @@ handle_dma_map_or_unmap(lm_ctx_t *lm_ctx, uint32_t size, bool map,
struct vfio_user_dma_region *dma_regions)
{
int nr_dma_regions;
- int ret, i;
+ int ret, i, fdi;
assert(lm_ctx != NULL);
assert(fds != NULL);
@@ -534,43 +534,35 @@ 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_fds > 0 && 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++) {
+ for (i = 0, fdi = 0; i < nr_dma_regions; i++) {
if (map) {
+ int fd = -1;
if (dma_regions[i].flags == VFIO_USER_F_DMA_REGION_MAPPABLE) {
- if (nr_fds == 0) {
- return -EINVAL;
- }
- } else {
- if (nr_fds != 0) {
+ if (fdi == nr_fds) {
return -EINVAL;
}
- fds[i] = -1;
+ 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,
diff --git a/lib/muser_priv.h b/lib/muser_priv.h
index 2d47d1a..ea44237 100644
--- a/lib/muser_priv.h
+++ b/lib/muser_priv.h
@@ -208,6 +208,10 @@ 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);
+void
+_dma_controller_do_remove_region(dma_controller_t *dma,
+ dma_memory_region_t *region);
+
#endif /* LIB_MUSER_PRIV_H */
/* ex: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */