diff options
author | John Levon <john.levon@nutanix.com> | 2021-05-10 12:59:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-10 12:59:01 +0100 |
commit | b95c886ed23b4cc4c539030bf383b55aae8859a3 (patch) | |
tree | d032be6eff881d8ff69ea94a29b459546876d97a /lib/dma.c | |
parent | 12ee57e1101e7059361d41011211bc4e8aef20fc (diff) | |
download | libvfio-user-b95c886ed23b4cc4c539030bf383b55aae8859a3.zip libvfio-user-b95c886ed23b4cc4c539030bf383b55aae8859a3.tar.gz libvfio-user-b95c886ed23b4cc4c539030bf383b55aae8859a3.tar.bz2 |
fix dma unregister callback during region removal (#464)
There are two issues with the unregister callback:
- we were requiring the callback to be set when removing a region, but it's
only required if a consumer wants to map regions
- when we removed all regions (for example, on a reset), we weren't triggering
the callback
Signed-off-by: John Levon <john.levon@nutanix.com>
swapnil code review
add assert
Reviewed-by: Swapnil Ingle <swapnil.ingle@nutanix.com>
Diffstat (limited to 'lib/dma.c')
-rw-r--r-- | lib/dma.c | 21 |
1 files changed, 14 insertions, 7 deletions
@@ -154,7 +154,7 @@ MOCK_DEFINE(dma_controller_remove_region)(dma_controller_t *dma, continue; } - err = dma_unregister(data, ®ion->info); + err = dma_unregister == NULL ? 0 : dma_unregister(data, ®ion->info); if (err != 0) { err = errno; vfu_log(dma->vfu_ctx, LOG_ERR, @@ -178,7 +178,9 @@ MOCK_DEFINE(dma_controller_remove_region)(dma_controller_t *dma, } void -dma_controller_remove_regions(dma_controller_t *dma) +dma_controller_remove_all_regions(dma_controller_t *dma, + vfu_dma_unregister_cb_t *dma_unregister, + void *data) { int i; @@ -186,6 +188,7 @@ dma_controller_remove_regions(dma_controller_t *dma) for (i = 0; i < dma->nregions; i++) { dma_memory_region_t *region = &dma->regions[i]; + int err; vfu_log(dma->vfu_ctx, LOG_DEBUG, "removing DMA region " "iova=[%p, %p) vaddr=%p mapping=[%p, %p)", @@ -193,6 +196,14 @@ dma_controller_remove_regions(dma_controller_t *dma) region->info.vaddr, region->info.mapping.iov_base, iov_end(®ion->info.mapping)); + err = dma_unregister == NULL ? 0 : dma_unregister(data, ®ion->info); + if (err != 0) { + err = errno; + vfu_log(dma->vfu_ctx, LOG_ERR, + "failed to dma_unregister() DMA region [%p, %p): %m", + region->info.iova.iov_base, iov_end(®ion->info.iova)); + } + if (region->info.vaddr != NULL) { dma_controller_unmap_region(dma, region); } else { @@ -207,11 +218,7 @@ dma_controller_remove_regions(dma_controller_t *dma) void dma_controller_destroy(dma_controller_t *dma) { - if (dma == NULL) { - return; - } - - dma_controller_remove_regions(dma); + assert(dma->nregions == 0); free(dma); } |