diff options
author | Thanos Makatos <thanos.makatos@nutanix.com> | 2021-05-25 16:18:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-25 16:18:48 +0100 |
commit | 4cc22bfd12ab10c1fbf20dd9d7b0633fb848bd9e (patch) | |
tree | 3c32d0e2bbb14bac0bb643bfcdfd9c345a3d3bd6 | |
parent | 6037d88be862d2afb91445a081f342e06e643e1e (diff) | |
download | libvfio-user-4cc22bfd12ab10c1fbf20dd9d7b0633fb848bd9e.zip libvfio-user-4cc22bfd12ab10c1fbf20dd9d7b0633fb848bd9e.tar.gz libvfio-user-4cc22bfd12ab10c1fbf20dd9d7b0633fb848bd9e.tar.bz2 |
don't treat DMA segment as absolute when determining dirty page bit (#519)
New DMA regions don't get their pages tracked if dirty page logging has
already been started, this patch fixes this bug.
Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Reviewed-by: John Levon <john.levon@nutanix.com>
-rw-r--r-- | lib/dma.h | 30 |
1 files changed, 2 insertions, 28 deletions
@@ -139,33 +139,6 @@ _dma_should_mark_dirty(const dma_controller_t *dma, int prot) return (prot & PROT_WRITE) == PROT_WRITE && dma->dirty_pgsize > 0; } -static size_t -_get_pgstart(size_t pgsize, void *base_addr, uint64_t offset) -{ - return (offset - (uint64_t)base_addr) / pgsize; -} - -static size_t -_get_pgend(size_t pgsize, uint64_t len, size_t start) -{ - return start + (len / pgsize) + (len % pgsize != 0) - 1; -} - -static void -_dma_bitmap_get_pgrange(const dma_controller_t *dma, - const dma_memory_region_t *region, - const dma_sg_t *sg, size_t *start, size_t *end) -{ - assert(dma != NULL); - assert(region != NULL); - assert(sg != NULL); - assert(start != NULL); - assert(end != NULL); - - *start = _get_pgstart(dma->dirty_pgsize, region->info.iova.iov_base, sg->offset); - *end = _get_pgend(dma->dirty_pgsize, sg->length, *start); -} - static void _dma_mark_dirty(const dma_controller_t *dma, const dma_memory_region_t *region, dma_sg_t *sg) @@ -177,7 +150,8 @@ _dma_mark_dirty(const dma_controller_t *dma, const dma_memory_region_t *region, assert(sg != NULL); assert(region->dirty_bitmap != NULL); - _dma_bitmap_get_pgrange(dma, region, sg, &start, &end); + start = sg->offset / dma->dirty_pgsize; + end = start + (sg->length / dma->dirty_pgsize) + (sg->length % dma->dirty_pgsize != 0) - 1; for (i = start; i <= end; i++) { region->dirty_bitmap[i / CHAR_BIT] |= 1 << (i % CHAR_BIT); } |