> From: Joao Martins <joao.m.martins@xxxxxxxxxx> > Sent: Friday, April 29, 2022 5:09 AM [...] > + > +static int iommu_read_and_clear_dirty(struct iommu_domain *domain, > + struct iommufd_dirty_data *bitmap) In a glance this function and all previous helpers doesn't rely on any iommufd objects except that the new structures are named as iommufd_xxx. I wonder whether moving all of them to the iommu layer would make more sense here. > +{ > + const struct iommu_domain_ops *ops = domain->ops; > + struct iommu_iotlb_gather gather; > + struct iommufd_dirty_iter iter; > + int ret = 0; > + > + if (!ops || !ops->read_and_clear_dirty) > + return -EOPNOTSUPP; > + > + iommu_dirty_bitmap_init(&iter.dirty, bitmap->iova, > + __ffs(bitmap->page_size), &gather); > + ret = iommufd_dirty_iter_init(&iter, bitmap); > + if (ret) > + return -ENOMEM; > + > + for (; iommufd_dirty_iter_done(&iter); > + iommufd_dirty_iter_advance(&iter)) { > + ret = iommufd_dirty_iter_get(&iter); > + if (ret) > + break; > + > + ret = ops->read_and_clear_dirty(domain, > + iommufd_dirty_iova(&iter), > + iommufd_dirty_iova_length(&iter), &iter.dirty); > + > + iommufd_dirty_iter_put(&iter); > + > + if (ret) > + break; > + } > + > + iommu_iotlb_sync(domain, &gather); > + iommufd_dirty_iter_free(&iter); > + > + return ret; > +} > +