[PATCH 4/7] vfio: iommu_type1: Fix missing dirty page when promote pinned_scope

Keqian Zhu
2020-12-10T07:37:08Z

When we pin or detach a group which is not dirty tracking capable,
we will try to promote pinned_scope of vfio_iommu.

If we succeed to do so, vfio only report pinned_scope as dirty to
userspace next time, but these memory written before pin or detach
is missed.

The solution is that we must populate all dma range as dirty before
promoting pinned_scope of vfio_iommu.

Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
drivers/vfio/vfio_iommu_type1.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index bd9a94590ebc..00684597b098 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -1633,6 +1633,20 @@ static struct vfio_group *vfio_iommu_find_iommu_group(struct vfio_iommu *iommu,
return group;
}

+static void vfio_populate_bitmap_all(struct vfio_iommu *iommu)
+{
+ struct rb_node *n;
+ unsigned long pgshift = __ffs(iommu->pgsize_bitmap);
+
+ for (n = rb_first(&iommu->dma_list); n; n = rb_next(n)) {
+ struct vfio_dma *dma = rb_entry(n, struct vfio_dma, node);
+ unsigned long nbits = dma->size >> pgshift;
+
+ if (dma->iommu_mapped)
+ bitmap_set(dma->bitmap, 0, nbits);
+ }
+}
+
static void promote_pinned_page_dirty_scope(struct vfio_iommu *iommu)
{
struct vfio_domain *domain;
@@ -1657,6 +1671,10 @@ static void promote_pinned_page_dirty_scope(struct vfio_iommu *iommu)
}

iommu->pinned_page_dirty_scope = true;
+
+ /* Set all bitmap to avoid missing dirty page */
+ if (iommu->dirty_page_tracking)
+ vfio_populate_bitmap_all(iommu);
}

static bool vfio_iommu_has_sw_msi(struct list_head *group_resv_regions,