aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThanos Makatos <thanos.makatos@nutanix.com>2020-12-17 15:52:18 +0000
committerGitHub <noreply@github.com>2020-12-17 15:52:18 +0000
commita764a3d66eb5a04dea769be15d88ef0ac4e5a5ea (patch)
treee78b28a2ec436ff9550bcaea765683311bcb7989 /lib
parentff70ca1a9f97feae62e326eca39624c13aa8117f (diff)
downloadlibvfio-user-a764a3d66eb5a04dea769be15d88ef0ac4e5a5ea.zip
libvfio-user-a764a3d66eb5a04dea769be15d88ef0ac4e5a5ea.tar.gz
libvfio-user-a764a3d66eb5a04dea769be15d88ef0ac4e5a5ea.tar.bz2
add mappable bit in DMA segment (#215)
remove duplicate code for initializing DMA segment, mark DMA segment whether it's mappable, plus basic unit test for dma_addr_to_sg Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/dma.c8
-rw-r--r--lib/dma.h23
2 files changed, 17 insertions, 14 deletions
diff --git a/lib/dma.c b/lib/dma.c
index 0bb623c..69b3fe5 100644
--- a/lib/dma.c
+++ b/lib/dma.c
@@ -375,13 +375,7 @@ _dma_addr_sg_split(const dma_controller_t *dma,
size_t region_len = MIN(region_end - dma_addr, len);
if (cnt < max_sg) {
- sg[cnt].dma_addr = region->dma_addr;
- sg[cnt].region = idx;
- sg[cnt].offset = dma_addr - region->dma_addr;
- sg[cnt].length = region_len;
- if (_dma_should_mark_dirty(dma, prot)) {
- _dma_mark_dirty(dma, region, sg);
- }
+ dma_init_sg(dma, sg, dma_addr, region_len, prot, idx);
}
cnt++;
diff --git a/lib/dma.h b/lib/dma.h
index aeed9bb..7bab3da 100644
--- a/lib/dma.h
+++ b/lib/dma.h
@@ -181,6 +181,21 @@ _dma_mark_dirty(const dma_controller_t *dma, const dma_memory_region_t *region,
}
}
+static inline void
+dma_init_sg(const dma_controller_t *dma, dma_sg_t *sg, dma_addr_t dma_addr,
+ uint32_t len, int prot, int region_index)
+{
+ const dma_memory_region_t *const region = &dma->regions[region_index];
+ sg->dma_addr = region->dma_addr;
+ sg->region = region_index;
+ sg->offset = dma_addr - region->dma_addr;
+ sg->length = len;
+ if (_dma_should_mark_dirty(dma, prot)) {
+ _dma_mark_dirty(dma, region, sg);
+ }
+ sg->mappable = region->virt_addr != NULL;
+}
+
/* Takes a linear dma address span and returns a sg list suitable for DMA.
* A single linear dma address span may need to be split into multiple
* scatter gather regions due to limitations of how memory can be mapped.
@@ -207,13 +222,7 @@ dma_addr_to_sg(const dma_controller_t *dma,
if (likely(max_sg > 0 && len > 0 &&
dma_addr >= region->dma_addr && dma_addr + len <= region_end &&
region_hint < dma->nregions)) {
- sg->dma_addr = region->dma_addr;
- sg->region = region_hint;
- sg->offset = dma_addr - region->dma_addr;
- sg->length = len;
- if (_dma_should_mark_dirty(dma, prot)) {
- _dma_mark_dirty(dma, region, sg);
- }
+ dma_init_sg(dma, sg, dma_addr, len, prot, region_hint);
return 1;
}
// Slow path: search through regions.