On 23/09/2023 02:25, Joao Martins wrote: > +static int amd_iommu_read_and_clear_dirty(struct iommu_domain *domain, > + unsigned long iova, size_t size, > + unsigned long flags, > + struct iommu_dirty_bitmap *dirty) > +{ > + struct protection_domain *pdomain = to_pdomain(domain); > + struct io_pgtable_ops *ops = &pdomain->iop.iop.ops; > + unsigned long lflags; > + int ret; > + > + if (!ops || !ops->read_and_clear_dirty) > + return -EOPNOTSUPP; > + > + spin_lock_irqsave(&pdomain->lock, lflags); > + if (!pdomain->dirty_tracking && dirty->bitmap) { > + spin_unlock_irqrestore(&pdomain->lock, lflags); > + return -EINVAL; > + } > + spin_unlock_irqrestore(&pdomain->lock, lflags); > + > + rcu_read_lock(); > + ret = ops->read_and_clear_dirty(ops, iova, size, flags, dirty); > + rcu_read_unlock(); > + > + return ret; > +} > + These rcu_read_{unlock,lock} are spurious given discussion on RFCv2 and is also removed for v4. I did remove from core code, but not the driver implementations still had these sprinkled here. Likewise, for Intel IOMMU implementation as well. > + > static void amd_iommu_get_resv_regions(struct device *dev, > struct list_head *head) > { > @@ -2500,6 +2593,11 @@ static bool amd_iommu_enforce_cache_coherency(struct iommu_domain *domain) > return true; > } > > +const struct iommu_dirty_ops amd_dirty_ops = { > + .set_dirty_tracking = amd_iommu_set_dirty_tracking, > + .read_and_clear_dirty = amd_iommu_read_and_clear_dirty, > +}; > + > const struct iommu_ops amd_iommu_ops = { > .capable = amd_iommu_capable, > .domain_alloc = amd_iommu_domain_alloc,