From: Keqian Zhu zhukeqian1@huawei.com
virt inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4WK5B 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 --- drivers/iommu/iommu.c | 25 ++++--------------------- include/linux/iommu.h | 1 - 2 files changed, 4 insertions(+), 22 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 25b3b8386ca9..9e7de0e5b9e8 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -3017,13 +3017,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); @@ -3046,11 +3039,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; } @@ -3077,10 +3068,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);
@@ -3101,7 +3088,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; } @@ -3163,10 +3150,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; - }
start = (iova - base_iova) >> bitmap_pgshift; end = start + (size >> bitmap_pgshift); @@ -3182,7 +3165,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; } diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 591a6c5d2ddf..8baf5ed66a84 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -87,7 +87,6 @@ struct iommu_domain { void *handler_token; struct iommu_domain_geometry geometry; void *iova_cookie; - bool dirty_log_tracking; struct mutex switch_log_lock; KABI_RESERVE(1) KABI_RESERVE(2)