if (!pasid_supported(iommu) || dev_is_real_dma_subdevice(dev))
return -EOPNOTSUPP;
- if (domain->dirty_ops)
- return -EINVAL;
-
if (context_copied(iommu, info->bus, info->devfn))
return -EBUSY;
static int domain_set_dirty_tracking(struct dmar_domain *domain, bool enable)
{
struct device_domain_info *info;
+ struct dev_pasid_info *dev_pasid;
int ret = 0;
lockdep_assert_held(&domain->lock);
list_for_each_entry(info, &domain->devices, link) {
ret = intel_pasid_setup_dirty_tracking(info->iommu, info->dev,
IOMMU_NO_PASID, enable);
+ if (ret)
+ return ret;
+ }
+
+ list_for_each_entry(dev_pasid, &domain->dev_pasids, link_domain) {
+ info = dev_iommu_priv_get(dev_pasid->dev);
+ ret = intel_pasid_setup_dirty_tracking(info->iommu, info->dev,
+ dev_pasid->pasid, enable);
if (ret)
break;
}
{
struct device_domain_info *info = dev_iommu_priv_get(dev);
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
- struct iommu_domain *s2_domain = &dmar_domain->s2_domain->domain;
struct intel_iommu *iommu = info->iommu;
struct dev_pasid_info *dev_pasid;
int ret;
if (!pasid_supported(iommu) || dev_is_real_dma_subdevice(dev))
return -EOPNOTSUPP;
- if (s2_domain->dirty_ops)
- return -EINVAL;
-
if (context_copied(iommu, info->bus, info->devfn))
return -EBUSY;
- ret = paging_domain_compatible(s2_domain, dev);
+ ret = paging_domain_compatible(&dmar_domain->s2_domain->domain, dev);
if (ret)
return ret;