aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSwapnil Ingle <swapnil.ingle@nutanix.com>2021-06-10 16:23:51 +0200
committerGitHub <noreply@github.com>2021-06-10 16:23:51 +0200
commit3fe0df4843508ffc3517e82e9256c0e2d02932bd (patch)
treec8b3dfe29d0a2166653a38f8efebd0aa8baf96bb /test
parent8b6db2e0b3b340dd747c735e48a4691619e063ce (diff)
downloadlibvfio-user-3fe0df4843508ffc3517e82e9256c0e2d02932bd.zip
libvfio-user-3fe0df4843508ffc3517e82e9256c0e2d02932bd.tar.gz
libvfio-user-3fe0df4843508ffc3517e82e9256c0e2d02932bd.tar.bz2
dma: Fix returned sg array (#564)
_dma_addr_sg_split() is supposed to return back sg's if the requested dma addr spans across regions. Also adding unit tests to cover these case. Signed-off-by: Swapnil Ingle <swapnil.ingle@nutanix.com> Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'test')
-rw-r--r--test/unit-tests.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/test/unit-tests.c b/test/unit-tests.c
index 8a41a76..bcfd348 100644
--- a/test/unit-tests.c
+++ b/test/unit-tests.c
@@ -387,8 +387,9 @@ test_dma_map_sg(void **state UNUSED)
static void
test_dma_addr_to_sg(void **state UNUSED)
{
- dma_memory_region_t *r;
- dma_sg_t sg;
+ dma_memory_region_t *r, *r1;
+ dma_sg_t sg[2];
+ struct iovec iov[2];
int ret;
vfu_ctx.dma->nregions = 1;
@@ -400,33 +401,60 @@ test_dma_addr_to_sg(void **state UNUSED)
/* fast path, region hint hit */
r->info.prot = PROT_WRITE;
ret = dma_addr_to_sg(vfu_ctx.dma, (vfu_dma_addr_t)0x2000,
- 0x400, &sg, 1, PROT_READ);
+ 0x400, sg, 1, PROT_READ);
assert_int_equal(1, ret);
- assert_int_equal(r->info.iova.iov_base, sg.dma_addr);
- assert_int_equal(0, sg.region);
+ assert_int_equal(r->info.iova.iov_base, sg[0].dma_addr);
+ assert_int_equal(0, sg[0].region);
assert_int_equal(0x2000 - (unsigned long long)r->info.iova.iov_base,
- sg.offset);
- assert_int_equal(0x400, sg.length);
- assert_true(vfu_sg_is_mappable(&vfu_ctx, &sg));
+ sg[0].offset);
+ assert_int_equal(0x400, sg[0].length);
+ assert_true(vfu_sg_is_mappable(&vfu_ctx, &sg[0]));
errno = 0;
r->info.prot = PROT_WRITE;
ret = dma_addr_to_sg(vfu_ctx.dma, (vfu_dma_addr_t)0x6000,
- 0x400, &sg, 1, PROT_READ);
+ 0x400, sg, 1, PROT_READ);
assert_int_equal(-1, ret);
assert_int_equal(ENOENT, errno);
r->info.prot = PROT_READ;
ret = dma_addr_to_sg(vfu_ctx.dma, (vfu_dma_addr_t)0x2000,
- 0x400, &sg, 1, PROT_WRITE);
+ 0x400, sg, 1, PROT_WRITE);
assert_int_equal(-1, ret);
assert_int_equal(EACCES, errno);
r->info.prot = PROT_READ|PROT_WRITE;
ret = dma_addr_to_sg(vfu_ctx.dma, (vfu_dma_addr_t)0x2000,
- 0x400, &sg, 1, PROT_READ);
+ 0x400, sg, 1, PROT_READ);
assert_int_equal(1, ret);
+ vfu_ctx.dma->nregions = 2;
+ r1 = &vfu_ctx.dma->regions[1];
+ r1->info.iova.iov_base = (void *)0x5000;
+ r1->info.iova.iov_len = 0x2000;
+ r1->info.vaddr = (void *)0xcafebabe;
+ r1->info.prot = PROT_WRITE;
+ ret = dma_addr_to_sg(vfu_ctx.dma, (vfu_dma_addr_t)0x1000,
+ 0x5000, sg, 2, PROT_READ);
+ assert_int_equal(2, ret);
+ assert_int_equal(0x4000, sg[0].length);
+ assert_int_equal(r->info.iova.iov_base, sg[0].dma_addr);
+ assert_int_equal(0, sg[0].region);
+ assert_int_equal(0, sg[0].offset);
+ assert_true(vfu_sg_is_mappable(&vfu_ctx, &sg[0]));
+
+ assert_int_equal(0x1000, sg[1].length);
+ assert_int_equal(r1->info.iova.iov_base, sg[1].dma_addr);
+ assert_int_equal(1, sg[1].region);
+ assert_int_equal(0, sg[1].offset);
+ assert_true(vfu_sg_is_mappable(&vfu_ctx, &sg[1]));
+
+ assert_int_equal(0, dma_map_sg(vfu_ctx.dma, sg, iov, 2));
+ assert_int_equal(r->info.vaddr + sg[0].offset, iov[0].iov_base);
+ assert_int_equal(sg[0].length, iov[0].iov_len);
+ assert_int_equal(r1->info.vaddr + sg[1].offset, iov[1].iov_base);
+ assert_int_equal(sg[1].length, iov[1].iov_len);
+
/* TODO test more scenarios */
}