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@xxxxxxxxxx> --- 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, -- 2.23.0 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm