diff options
author | Swapnil Ingle <swapnil.ingle@nutanix.com> | 2021-06-10 16:23:51 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-10 16:23:51 +0200 |
commit | 3fe0df4843508ffc3517e82e9256c0e2d02932bd (patch) | |
tree | c8b3dfe29d0a2166653a38f8efebd0aa8baf96bb /test | |
parent | 8b6db2e0b3b340dd747c735e48a4691619e063ce (diff) | |
download | libvfio-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.c | 50 |
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 */ } |