From f098c23e597ee715463222aee1ee804cb9cb928f Mon Sep 17 00:00:00 2001 From: Yong Wu Date: Thu, 7 Jan 2021 20:29:04 +0800 Subject: [PATCH] BACKPORT: UPSTREAM: iommu: Add iova and size as parameters in iotlb_sync_map iotlb_sync_map allow IOMMU drivers tlb sync after completing the whole mapping. This patch adds iova and size as the parameters in it. then the IOMMU driver could flush tlb with the whole range once after iova mapping to improve performance. Signed-off-by: Yong Wu Reviewed-by: Robin Murphy Acked-by: Will Deacon Link: https://lore.kernel.org/r/20210107122909.16317-3-yong.wu@mediatek.com Signed-off-by: Will Deacon (cherry picked from commit 2ebbd25873cef06f739489fd8ff9f707a3dfa2fa) (YongWu: this branch has this commit which is not in mainline: c8ab4bae5895 FROMLIST: iommu: Introduce map_sg() as an IOMMU op for IOMMU drivers ) BUG=b:174513569 Signed-off-by: Yong Wu Change-Id: Ie463d3cf7efa9320661e7e5fb0042f54d9f1a892 --- drivers/iommu/iommu.c | 6 +++--- drivers/iommu/tegra-gart.c | 7 +++++-- include/linux/iommu.h | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index a7b18286a091..58ac0f8bca68 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2426,7 +2426,7 @@ static int _iommu_map(struct iommu_domain *domain, unsigned long iova, ret = __iommu_map(domain, iova, paddr, size, prot, gfp); if (ret == 0 && ops->iotlb_sync_map) - ops->iotlb_sync_map(domain); + ops->iotlb_sync_map(domain, iova, size); return ret; } @@ -2536,7 +2536,7 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova, ret = ops->map_sg(domain, iova, sg, nents, prot, gfp, &mapped); if (ops->iotlb_sync_map) - ops->iotlb_sync_map(domain); + ops->iotlb_sync_map(domain, iova, mapped); if (ret) goto out_err; @@ -2570,7 +2570,7 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova, } if (ops->iotlb_sync_map) - ops->iotlb_sync_map(domain); + ops->iotlb_sync_map(domain, iova, mapped); return mapped; out_err: diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c index fac720273889..05e8e19b8269 100644 --- a/drivers/iommu/tegra-gart.c +++ b/drivers/iommu/tegra-gart.c @@ -261,7 +261,8 @@ static int gart_iommu_of_xlate(struct device *dev, return 0; } -static void gart_iommu_sync_map(struct iommu_domain *domain) +static void gart_iommu_sync_map(struct iommu_domain *domain, unsigned long iova, + size_t size) { FLUSH_GART_REGS(gart_handle); } @@ -269,7 +270,9 @@ static void gart_iommu_sync_map(struct iommu_domain *domain) static void gart_iommu_sync(struct iommu_domain *domain, struct iommu_iotlb_gather *gather) { - gart_iommu_sync_map(domain); + size_t length = gather->end - gather->start; + + gart_iommu_sync_map(domain, gather->start, length); } static const struct iommu_ops gart_iommu_ops = { diff --git a/include/linux/iommu.h b/include/linux/iommu.h index a17f31976107..7353ad3c2bdb 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -262,7 +262,8 @@ struct iommu_ops { size_t (*unmap)(struct iommu_domain *domain, unsigned long iova, size_t size, struct iommu_iotlb_gather *iotlb_gather); void (*flush_iotlb_all)(struct iommu_domain *domain); - void (*iotlb_sync_map)(struct iommu_domain *domain); + void (*iotlb_sync_map)(struct iommu_domain *domain, unsigned long iova, + size_t size); void (*iotlb_sync)(struct iommu_domain *domain, struct iommu_iotlb_gather *iotlb_gather); phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);