iommu: Improve iommu_iotlb_gather helpers
authorRobin Murphy <robin.murphy@arm.com>
Fri, 23 Jul 2021 09:32:05 +0000 (02:32 -0700)
committerJoerg Roedel <jroedel@suse.de>
Mon, 2 Aug 2021 09:26:05 +0000 (11:26 +0200)
The Mediatek driver is not the only one which might want a basic
address-based gathering behaviour, so although it's arguably simple
enough to open-code, let's factor it out for the sake of cleanliness.
Let's also take this opportunity to document the intent of these
helpers for clarity.

Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <will@kernel.org>
Cc: Jiajun Cao <caojiajun@vmware.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Lu Baolu <baolu.lu@linux.intel.com>
Cc: iommu@lists.linux-foundation.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Nadav Amit <namit@vmware.com>
Link: https://lore.kernel.org/r/20210723093209.714328-4-namit@vmware.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/mtk_iommu.c
include/linux/iommu.h

index 6f7c69688ce2ae4922a2586d6595706c9f234352..d9939e4af35c656d363a6645486fe6ea388c36af 100644 (file)
@@ -520,12 +520,8 @@ static size_t mtk_iommu_unmap(struct iommu_domain *domain,
                              struct iommu_iotlb_gather *gather)
 {
        struct mtk_iommu_domain *dom = to_mtk_domain(domain);
-       unsigned long end = iova + size - 1;
 
-       if (gather->start > iova)
-               gather->start = iova;
-       if (gather->end < end)
-               gather->end = end;
+       iommu_iotlb_gather_add_range(gather, iova, size);
        return dom->iop->unmap(dom->iop, iova, size, gather);
 }
 
index 32d448050bf76eaf072cf705b9413a8db9cf344b..e554871db46fc8471db5ffb2260cbce472feb1cc 100644 (file)
@@ -497,6 +497,38 @@ static inline void iommu_iotlb_sync(struct iommu_domain *domain,
        iommu_iotlb_gather_init(iotlb_gather);
 }
 
+/**
+ * iommu_iotlb_gather_add_range - Gather for address-based TLB invalidation
+ * @gather: TLB gather data
+ * @iova: start of page to invalidate
+ * @size: size of page to invalidate
+ *
+ * Helper for IOMMU drivers to build arbitrarily-sized invalidation commands
+ * where only the address range matters, and simply minimising intermediate
+ * syncs is preferred.
+ */
+static inline void iommu_iotlb_gather_add_range(struct iommu_iotlb_gather *gather,
+                                               unsigned long iova, size_t size)
+{
+       unsigned long end = iova + size - 1;
+
+       if (gather->start > iova)
+               gather->start = iova;
+       if (gather->end < end)
+               gather->end = end;
+}
+
+/**
+ * iommu_iotlb_gather_add_page - Gather for page-based TLB invalidation
+ * @domain: IOMMU domain to be invalidated
+ * @gather: TLB gather data
+ * @iova: start of page to invalidate
+ * @size: size of page to invalidate
+ *
+ * Helper for IOMMU drivers to build invalidation commands based on individual
+ * pages, or with page size/table level hints which cannot be gathered if they
+ * differ.
+ */
 static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,
                                               struct iommu_iotlb_gather *gather,
                                               unsigned long iova, size_t size)
@@ -515,11 +547,7 @@ static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,
                gather->pgsize = size;
        }
 
-       if (gather->end < end)
-               gather->end = end;
-
-       if (gather->start > start)
-               gather->start = start;
+       iommu_iotlb_gather_add_range(gather, iova, size);
 }
 
 /* PCI device grouping function */