From: Keqian Zhu zhukeqian1@huawei.com
virt inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8UZSP CVE: NA
------------------------------
The iommu_domain may contain more than one DMA range which can be dirty log tracked separately, so it's hard to track the dirty log status of iommu_domain. The upper layer (e.g. vfio) should make sure it's doing right thing.
Fixes: bbf3b39e5576 (iommu: Introduce dirty log tracking framework) Signed-off-by: Keqian Zhu zhukeqian1@huawei.com Tested-by: Kunkun Jiang jiangkunkun@huawei.com Reviewed-by: Kunkun Jiang jiangkunkun@huawei.com Reviewed-by: Zenghui Yu yuzenghui@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: jiaqingtong jiaqingtong@huawei.com --- drivers/iommu/iommu.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index dbae8a71c0f0..32f0f6c461b3 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2777,13 +2777,6 @@ int iommu_switch_dirty_log(struct iommu_domain *domain, bool enable, }
mutex_lock(&domain->switch_log_lock); - if (enable && domain->dirty_log_tracking) { - ret = -EBUSY; - goto out; - } else if (!enable && !domain->dirty_log_tracking) { - ret = -EINVAL; - goto out; - }
pr_debug("switch_dirty_log %s for: iova 0x%lx size 0x%zx\n", enable ? "enable" : "disable", iova, size); @@ -2806,11 +2799,9 @@ int iommu_switch_dirty_log(struct iommu_domain *domain, bool enable, if (flush) iommu_flush_iotlb_all(domain);
- if (!ret) { - domain->dirty_log_tracking = enable; + if (!ret) trace_switch_dirty_log(orig_iova, orig_size, enable); - } -out: + mutex_unlock(&domain->switch_log_lock); return ret; } @@ -2837,10 +2828,6 @@ int iommu_sync_dirty_log(struct iommu_domain *domain, unsigned long iova, }
mutex_lock(&domain->switch_log_lock); - if (!domain->dirty_log_tracking) { - ret = -EINVAL; - goto out; - }
pr_debug("sync_dirty_log for: iova 0x%lx size 0x%zx\n", iova, size);
@@ -2861,7 +2848,7 @@ int iommu_sync_dirty_log(struct iommu_domain *domain, unsigned long iova,
if (!ret) trace_sync_dirty_log(orig_iova, orig_size); -out: + mutex_unlock(&domain->switch_log_lock); return ret; } @@ -2922,10 +2909,6 @@ int iommu_clear_dirty_log(struct iommu_domain *domain, }
mutex_lock(&domain->switch_log_lock); - if (!domain->dirty_log_tracking) { - ret = -EINVAL; - goto out; - }
rs = (iova - base_iova) >> bitmap_pgshift; for_each_set_bitrange_from(rs, re, bitmap, (size >> bitmap_pgshift)) { @@ -2940,7 +2923,7 @@ int iommu_clear_dirty_log(struct iommu_domain *domain,
if (flush) iommu_flush_iotlb_all(domain); -out: + mutex_unlock(&domain->switch_log_lock); return ret; }