diff options
author | Will Deacon <will@kernel.org> | 2019-07-02 11:44:06 -0400 |
---|---|---|
committer | Will Deacon <will@kernel.org> | 2019-07-29 12:22:52 -0400 |
commit | 56f8af5e9d38f120cba2c2adb0786fa2dbc901a4 (patch) | |
tree | b46a5f01874bd1543e610949be6171296cd6300e | |
parent | 4fcf8544fc677fc8af135f1d86b3ba69c4ad429d (diff) |
iommu: Pass struct iommu_iotlb_gather to ->unmap() and ->iotlb_sync()
To allow IOMMU drivers to batch up TLB flushing operations and postpone
them until ->iotlb_sync() is called, extend the prototypes for the
->unmap() and ->iotlb_sync() IOMMU ops callbacks to take a pointer to
the current iommu_iotlb_gather structure.
All affected IOMMU drivers are updated, but there should be no
functional change since the extra parameter is ignored for now.
Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r-- | drivers/iommu/amd_iommu.c | 11 | ||||
-rw-r--r-- | drivers/iommu/arm-smmu-v3.c | 7 | ||||
-rw-r--r-- | drivers/iommu/arm-smmu.c | 5 | ||||
-rw-r--r-- | drivers/iommu/exynos-iommu.c | 3 | ||||
-rw-r--r-- | drivers/iommu/intel-iommu.c | 3 | ||||
-rw-r--r-- | drivers/iommu/iommu.c | 2 | ||||
-rw-r--r-- | drivers/iommu/ipmmu-vmsa.c | 12 | ||||
-rw-r--r-- | drivers/iommu/msm_iommu.c | 2 | ||||
-rw-r--r-- | drivers/iommu/mtk_iommu.c | 13 | ||||
-rw-r--r-- | drivers/iommu/mtk_iommu_v1.c | 3 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu.c | 2 | ||||
-rw-r--r-- | drivers/iommu/qcom_iommu.c | 12 | ||||
-rw-r--r-- | drivers/iommu/rockchip-iommu.c | 2 | ||||
-rw-r--r-- | drivers/iommu/s390-iommu.c | 3 | ||||
-rw-r--r-- | drivers/iommu/tegra-gart.c | 12 | ||||
-rw-r--r-- | drivers/iommu/tegra-smmu.c | 2 | ||||
-rw-r--r-- | drivers/iommu/virtio-iommu.c | 5 | ||||
-rw-r--r-- | include/linux/iommu.h | 7 |
18 files changed, 73 insertions, 33 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index f93b148cf55e..29eeea914660 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -3055,7 +3055,8 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, | |||
3055 | } | 3055 | } |
3056 | 3056 | ||
3057 | static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, | 3057 | static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, |
3058 | size_t page_size) | 3058 | size_t page_size, |
3059 | struct iommu_iotlb_gather *gather) | ||
3059 | { | 3060 | { |
3060 | struct protection_domain *domain = to_pdomain(dom); | 3061 | struct protection_domain *domain = to_pdomain(dom); |
3061 | size_t unmap_size; | 3062 | size_t unmap_size; |
@@ -3196,6 +3197,12 @@ static void amd_iommu_flush_iotlb_all(struct iommu_domain *domain) | |||
3196 | domain_flush_complete(dom); | 3197 | domain_flush_complete(dom); |
3197 | } | 3198 | } |
3198 | 3199 | ||
3200 | static void amd_iommu_iotlb_sync(struct iommu_domain *domain, | ||
3201 | struct iommu_iotlb_gather *gather) | ||
3202 | { | ||
3203 | amd_iommu_flush_iotlb_all(domain); | ||
3204 | } | ||
3205 | |||
3199 | const struct iommu_ops amd_iommu_ops = { | 3206 | const struct iommu_ops amd_iommu_ops = { |
3200 | .capable = amd_iommu_capable, | 3207 | .capable = amd_iommu_capable, |
3201 | .domain_alloc = amd_iommu_domain_alloc, | 3208 | .domain_alloc = amd_iommu_domain_alloc, |
@@ -3214,7 +3221,7 @@ const struct iommu_ops amd_iommu_ops = { | |||
3214 | .is_attach_deferred = amd_iommu_is_attach_deferred, | 3221 | .is_attach_deferred = amd_iommu_is_attach_deferred, |
3215 | .pgsize_bitmap = AMD_IOMMU_PGSIZES, | 3222 | .pgsize_bitmap = AMD_IOMMU_PGSIZES, |
3216 | .flush_iotlb_all = amd_iommu_flush_iotlb_all, | 3223 | .flush_iotlb_all = amd_iommu_flush_iotlb_all, |
3217 | .iotlb_sync = amd_iommu_flush_iotlb_all, | 3224 | .iotlb_sync = amd_iommu_iotlb_sync, |
3218 | }; | 3225 | }; |
3219 | 3226 | ||
3220 | /***************************************************************************** | 3227 | /***************************************************************************** |
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 7e137e1e28f1..80753b8ca054 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c | |||
@@ -1985,8 +1985,8 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, | |||
1985 | return ops->map(ops, iova, paddr, size, prot); | 1985 | return ops->map(ops, iova, paddr, size, prot); |
1986 | } | 1986 | } |
1987 | 1987 | ||
1988 | static size_t | 1988 | static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, |
1989 | arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) | 1989 | size_t size, struct iommu_iotlb_gather *gather) |
1990 | { | 1990 | { |
1991 | int ret; | 1991 | int ret; |
1992 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); | 1992 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
@@ -2010,7 +2010,8 @@ static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain) | |||
2010 | arm_smmu_tlb_inv_context(smmu_domain); | 2010 | arm_smmu_tlb_inv_context(smmu_domain); |
2011 | } | 2011 | } |
2012 | 2012 | ||
2013 | static void arm_smmu_iotlb_sync(struct iommu_domain *domain) | 2013 | static void arm_smmu_iotlb_sync(struct iommu_domain *domain, |
2014 | struct iommu_iotlb_gather *gather) | ||
2014 | { | 2015 | { |
2015 | struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; | 2016 | struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; |
2016 | 2017 | ||
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index dc08db347ef3..e535ae2a9e65 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -1301,7 +1301,7 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, | |||
1301 | } | 1301 | } |
1302 | 1302 | ||
1303 | static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, | 1303 | static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, |
1304 | size_t size) | 1304 | size_t size, struct iommu_iotlb_gather *gather) |
1305 | { | 1305 | { |
1306 | struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; | 1306 | struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; |
1307 | struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; | 1307 | struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; |
@@ -1329,7 +1329,8 @@ static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain) | |||
1329 | } | 1329 | } |
1330 | } | 1330 | } |
1331 | 1331 | ||
1332 | static void arm_smmu_iotlb_sync(struct iommu_domain *domain) | 1332 | static void arm_smmu_iotlb_sync(struct iommu_domain *domain, |
1333 | struct iommu_iotlb_gather *gather) | ||
1333 | { | 1334 | { |
1334 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); | 1335 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1335 | struct arm_smmu_device *smmu = smmu_domain->smmu; | 1336 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index b0c1e5f9daae..cf5af34cb681 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c | |||
@@ -1130,7 +1130,8 @@ static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *domain | |||
1130 | } | 1130 | } |
1131 | 1131 | ||
1132 | static size_t exynos_iommu_unmap(struct iommu_domain *iommu_domain, | 1132 | static size_t exynos_iommu_unmap(struct iommu_domain *iommu_domain, |
1133 | unsigned long l_iova, size_t size) | 1133 | unsigned long l_iova, size_t size, |
1134 | struct iommu_iotlb_gather *gather) | ||
1134 | { | 1135 | { |
1135 | struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain); | 1136 | struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain); |
1136 | sysmmu_iova_t iova = (sysmmu_iova_t)l_iova; | 1137 | sysmmu_iova_t iova = (sysmmu_iova_t)l_iova; |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index ac4172c02244..b9fb8d6ddc6e 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -5147,7 +5147,8 @@ static int intel_iommu_map(struct iommu_domain *domain, | |||
5147 | } | 5147 | } |
5148 | 5148 | ||
5149 | static size_t intel_iommu_unmap(struct iommu_domain *domain, | 5149 | static size_t intel_iommu_unmap(struct iommu_domain *domain, |
5150 | unsigned long iova, size_t size) | 5150 | unsigned long iova, size_t size, |
5151 | struct iommu_iotlb_gather *gather) | ||
5151 | { | 5152 | { |
5152 | struct dmar_domain *dmar_domain = to_dmar_domain(domain); | 5153 | struct dmar_domain *dmar_domain = to_dmar_domain(domain); |
5153 | struct page *freelist = NULL; | 5154 | struct page *freelist = NULL; |
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d67222fdfe44..70bfbcc09248 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c | |||
@@ -1899,7 +1899,7 @@ static size_t __iommu_unmap(struct iommu_domain *domain, | |||
1899 | while (unmapped < size) { | 1899 | while (unmapped < size) { |
1900 | size_t pgsize = iommu_pgsize(domain, iova, size - unmapped); | 1900 | size_t pgsize = iommu_pgsize(domain, iova, size - unmapped); |
1901 | 1901 | ||
1902 | unmapped_page = ops->unmap(domain, iova, pgsize); | 1902 | unmapped_page = ops->unmap(domain, iova, pgsize, iotlb_gather); |
1903 | if (!unmapped_page) | 1903 | if (!unmapped_page) |
1904 | break; | 1904 | break; |
1905 | 1905 | ||
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 2c14a2c65b22..a9332b893ce2 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c | |||
@@ -733,14 +733,14 @@ static int ipmmu_map(struct iommu_domain *io_domain, unsigned long iova, | |||
733 | } | 733 | } |
734 | 734 | ||
735 | static size_t ipmmu_unmap(struct iommu_domain *io_domain, unsigned long iova, | 735 | static size_t ipmmu_unmap(struct iommu_domain *io_domain, unsigned long iova, |
736 | size_t size) | 736 | size_t size, struct iommu_iotlb_gather *gather) |
737 | { | 737 | { |
738 | struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain); | 738 | struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain); |
739 | 739 | ||
740 | return domain->iop->unmap(domain->iop, iova, size); | 740 | return domain->iop->unmap(domain->iop, iova, size); |
741 | } | 741 | } |
742 | 742 | ||
743 | static void ipmmu_iotlb_sync(struct iommu_domain *io_domain) | 743 | static void ipmmu_flush_iotlb_all(struct iommu_domain *io_domain) |
744 | { | 744 | { |
745 | struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain); | 745 | struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain); |
746 | 746 | ||
@@ -748,6 +748,12 @@ static void ipmmu_iotlb_sync(struct iommu_domain *io_domain) | |||
748 | ipmmu_tlb_flush_all(domain); | 748 | ipmmu_tlb_flush_all(domain); |
749 | } | 749 | } |
750 | 750 | ||
751 | static void ipmmu_iotlb_sync(struct iommu_domain *io_domain, | ||
752 | struct iommu_iotlb_gather *gather) | ||
753 | { | ||
754 | ipmmu_flush_iotlb_all(io_domain); | ||
755 | } | ||
756 | |||
751 | static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain, | 757 | static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain, |
752 | dma_addr_t iova) | 758 | dma_addr_t iova) |
753 | { | 759 | { |
@@ -957,7 +963,7 @@ static const struct iommu_ops ipmmu_ops = { | |||
957 | .detach_dev = ipmmu_detach_device, | 963 | .detach_dev = ipmmu_detach_device, |
958 | .map = ipmmu_map, | 964 | .map = ipmmu_map, |
959 | .unmap = ipmmu_unmap, | 965 | .unmap = ipmmu_unmap, |
960 | .flush_iotlb_all = ipmmu_iotlb_sync, | 966 | .flush_iotlb_all = ipmmu_flush_iotlb_all, |
961 | .iotlb_sync = ipmmu_iotlb_sync, | 967 | .iotlb_sync = ipmmu_iotlb_sync, |
962 | .iova_to_phys = ipmmu_iova_to_phys, | 968 | .iova_to_phys = ipmmu_iova_to_phys, |
963 | .add_device = ipmmu_add_device, | 969 | .add_device = ipmmu_add_device, |
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 8b602384a385..681ab3d3376d 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c | |||
@@ -509,7 +509,7 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long iova, | |||
509 | } | 509 | } |
510 | 510 | ||
511 | static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long iova, | 511 | static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long iova, |
512 | size_t len) | 512 | size_t len, struct iommu_iotlb_gather *gather) |
513 | { | 513 | { |
514 | struct msm_priv *priv = to_msm_priv(domain); | 514 | struct msm_priv *priv = to_msm_priv(domain); |
515 | unsigned long flags; | 515 | unsigned long flags; |
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index fed77658d67e..c870f1674903 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c | |||
@@ -371,7 +371,8 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, | |||
371 | } | 371 | } |
372 | 372 | ||
373 | static size_t mtk_iommu_unmap(struct iommu_domain *domain, | 373 | static size_t mtk_iommu_unmap(struct iommu_domain *domain, |
374 | unsigned long iova, size_t size) | 374 | unsigned long iova, size_t size, |
375 | struct iommu_iotlb_gather *gather) | ||
375 | { | 376 | { |
376 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 377 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); |
377 | unsigned long flags; | 378 | unsigned long flags; |
@@ -384,7 +385,13 @@ static size_t mtk_iommu_unmap(struct iommu_domain *domain, | |||
384 | return unmapsz; | 385 | return unmapsz; |
385 | } | 386 | } |
386 | 387 | ||
387 | static void mtk_iommu_iotlb_sync(struct iommu_domain *domain) | 388 | static void mtk_iommu_flush_iotlb_all(struct iommu_domain *domain) |
389 | { | ||
390 | mtk_iommu_tlb_sync(mtk_iommu_get_m4u_data()); | ||
391 | } | ||
392 | |||
393 | static void mtk_iommu_iotlb_sync(struct iommu_domain *domain, | ||
394 | struct iommu_iotlb_gather *gather) | ||
388 | { | 395 | { |
389 | mtk_iommu_tlb_sync(mtk_iommu_get_m4u_data()); | 396 | mtk_iommu_tlb_sync(mtk_iommu_get_m4u_data()); |
390 | } | 397 | } |
@@ -490,7 +497,7 @@ static const struct iommu_ops mtk_iommu_ops = { | |||
490 | .detach_dev = mtk_iommu_detach_device, | 497 | .detach_dev = mtk_iommu_detach_device, |
491 | .map = mtk_iommu_map, | 498 | .map = mtk_iommu_map, |
492 | .unmap = mtk_iommu_unmap, | 499 | .unmap = mtk_iommu_unmap, |
493 | .flush_iotlb_all = mtk_iommu_iotlb_sync, | 500 | .flush_iotlb_all = mtk_iommu_flush_iotlb_all, |
494 | .iotlb_sync = mtk_iommu_iotlb_sync, | 501 | .iotlb_sync = mtk_iommu_iotlb_sync, |
495 | .iova_to_phys = mtk_iommu_iova_to_phys, | 502 | .iova_to_phys = mtk_iommu_iova_to_phys, |
496 | .add_device = mtk_iommu_add_device, | 503 | .add_device = mtk_iommu_add_device, |
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index abeeac488372..7b92ddd5d9fd 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c | |||
@@ -324,7 +324,8 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, | |||
324 | } | 324 | } |
325 | 325 | ||
326 | static size_t mtk_iommu_unmap(struct iommu_domain *domain, | 326 | static size_t mtk_iommu_unmap(struct iommu_domain *domain, |
327 | unsigned long iova, size_t size) | 327 | unsigned long iova, size_t size, |
328 | struct iommu_iotlb_gather *gather) | ||
328 | { | 329 | { |
329 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 330 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); |
330 | unsigned long flags; | 331 | unsigned long flags; |
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index dfb961d8c21b..8039bc5ee425 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c | |||
@@ -1149,7 +1149,7 @@ static int omap_iommu_map(struct iommu_domain *domain, unsigned long da, | |||
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da, | 1151 | static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da, |
1152 | size_t size) | 1152 | size_t size, struct iommu_iotlb_gather *gather) |
1153 | { | 1153 | { |
1154 | struct omap_iommu_domain *omap_domain = to_omap_domain(domain); | 1154 | struct omap_iommu_domain *omap_domain = to_omap_domain(domain); |
1155 | struct device *dev = omap_domain->dev; | 1155 | struct device *dev = omap_domain->dev; |
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c index fd9d9f4da735..a7432991fa04 100644 --- a/drivers/iommu/qcom_iommu.c +++ b/drivers/iommu/qcom_iommu.c | |||
@@ -417,7 +417,7 @@ static int qcom_iommu_map(struct iommu_domain *domain, unsigned long iova, | |||
417 | } | 417 | } |
418 | 418 | ||
419 | static size_t qcom_iommu_unmap(struct iommu_domain *domain, unsigned long iova, | 419 | static size_t qcom_iommu_unmap(struct iommu_domain *domain, unsigned long iova, |
420 | size_t size) | 420 | size_t size, struct iommu_iotlb_gather *gather) |
421 | { | 421 | { |
422 | size_t ret; | 422 | size_t ret; |
423 | unsigned long flags; | 423 | unsigned long flags; |
@@ -441,7 +441,7 @@ static size_t qcom_iommu_unmap(struct iommu_domain *domain, unsigned long iova, | |||
441 | return ret; | 441 | return ret; |
442 | } | 442 | } |
443 | 443 | ||
444 | static void qcom_iommu_iotlb_sync(struct iommu_domain *domain) | 444 | static void qcom_iommu_flush_iotlb_all(struct iommu_domain *domain) |
445 | { | 445 | { |
446 | struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain); | 446 | struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain); |
447 | struct io_pgtable *pgtable = container_of(qcom_domain->pgtbl_ops, | 447 | struct io_pgtable *pgtable = container_of(qcom_domain->pgtbl_ops, |
@@ -454,6 +454,12 @@ static void qcom_iommu_iotlb_sync(struct iommu_domain *domain) | |||
454 | pm_runtime_put_sync(qcom_domain->iommu->dev); | 454 | pm_runtime_put_sync(qcom_domain->iommu->dev); |
455 | } | 455 | } |
456 | 456 | ||
457 | static void qcom_iommu_iotlb_sync(struct iommu_domain *domain, | ||
458 | struct iommu_iotlb_gather *gather) | ||
459 | { | ||
460 | qcom_iommu_flush_iotlb_all(domain); | ||
461 | } | ||
462 | |||
457 | static phys_addr_t qcom_iommu_iova_to_phys(struct iommu_domain *domain, | 463 | static phys_addr_t qcom_iommu_iova_to_phys(struct iommu_domain *domain, |
458 | dma_addr_t iova) | 464 | dma_addr_t iova) |
459 | { | 465 | { |
@@ -581,7 +587,7 @@ static const struct iommu_ops qcom_iommu_ops = { | |||
581 | .detach_dev = qcom_iommu_detach_dev, | 587 | .detach_dev = qcom_iommu_detach_dev, |
582 | .map = qcom_iommu_map, | 588 | .map = qcom_iommu_map, |
583 | .unmap = qcom_iommu_unmap, | 589 | .unmap = qcom_iommu_unmap, |
584 | .flush_iotlb_all = qcom_iommu_iotlb_sync, | 590 | .flush_iotlb_all = qcom_iommu_flush_iotlb_all, |
585 | .iotlb_sync = qcom_iommu_iotlb_sync, | 591 | .iotlb_sync = qcom_iommu_iotlb_sync, |
586 | .iova_to_phys = qcom_iommu_iova_to_phys, | 592 | .iova_to_phys = qcom_iommu_iova_to_phys, |
587 | .add_device = qcom_iommu_add_device, | 593 | .add_device = qcom_iommu_add_device, |
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index dc26d74d79c2..26290f310f90 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c | |||
@@ -794,7 +794,7 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova, | |||
794 | } | 794 | } |
795 | 795 | ||
796 | static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova, | 796 | static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova, |
797 | size_t size) | 797 | size_t size, struct iommu_iotlb_gather *gather) |
798 | { | 798 | { |
799 | struct rk_iommu_domain *rk_domain = to_rk_domain(domain); | 799 | struct rk_iommu_domain *rk_domain = to_rk_domain(domain); |
800 | unsigned long flags; | 800 | unsigned long flags; |
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c index 22d4db302c1c..3b0b18e23187 100644 --- a/drivers/iommu/s390-iommu.c +++ b/drivers/iommu/s390-iommu.c | |||
@@ -314,7 +314,8 @@ static phys_addr_t s390_iommu_iova_to_phys(struct iommu_domain *domain, | |||
314 | } | 314 | } |
315 | 315 | ||
316 | static size_t s390_iommu_unmap(struct iommu_domain *domain, | 316 | static size_t s390_iommu_unmap(struct iommu_domain *domain, |
317 | unsigned long iova, size_t size) | 317 | unsigned long iova, size_t size, |
318 | struct iommu_iotlb_gather *gather) | ||
318 | { | 319 | { |
319 | struct s390_domain *s390_domain = to_s390_domain(domain); | 320 | struct s390_domain *s390_domain = to_s390_domain(domain); |
320 | int flags = ZPCI_PTE_INVALID; | 321 | int flags = ZPCI_PTE_INVALID; |
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c index 6d40bc1b38bf..3924f7c05544 100644 --- a/drivers/iommu/tegra-gart.c +++ b/drivers/iommu/tegra-gart.c | |||
@@ -207,7 +207,7 @@ static inline int __gart_iommu_unmap(struct gart_device *gart, | |||
207 | } | 207 | } |
208 | 208 | ||
209 | static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova, | 209 | static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova, |
210 | size_t bytes) | 210 | size_t bytes, struct iommu_iotlb_gather *gather) |
211 | { | 211 | { |
212 | struct gart_device *gart = gart_handle; | 212 | struct gart_device *gart = gart_handle; |
213 | int err; | 213 | int err; |
@@ -273,11 +273,17 @@ static int gart_iommu_of_xlate(struct device *dev, | |||
273 | return 0; | 273 | return 0; |
274 | } | 274 | } |
275 | 275 | ||
276 | static void gart_iommu_sync(struct iommu_domain *domain) | 276 | static void gart_iommu_sync_map(struct iommu_domain *domain) |
277 | { | 277 | { |
278 | FLUSH_GART_REGS(gart_handle); | 278 | FLUSH_GART_REGS(gart_handle); |
279 | } | 279 | } |
280 | 280 | ||
281 | static void gart_iommu_sync(struct iommu_domain *domain, | ||
282 | struct iommu_iotlb_gather *gather) | ||
283 | { | ||
284 | gart_iommu_sync_map(domain); | ||
285 | } | ||
286 | |||
281 | static const struct iommu_ops gart_iommu_ops = { | 287 | static const struct iommu_ops gart_iommu_ops = { |
282 | .capable = gart_iommu_capable, | 288 | .capable = gart_iommu_capable, |
283 | .domain_alloc = gart_iommu_domain_alloc, | 289 | .domain_alloc = gart_iommu_domain_alloc, |
@@ -292,7 +298,7 @@ static const struct iommu_ops gart_iommu_ops = { | |||
292 | .iova_to_phys = gart_iommu_iova_to_phys, | 298 | .iova_to_phys = gart_iommu_iova_to_phys, |
293 | .pgsize_bitmap = GART_IOMMU_PGSIZES, | 299 | .pgsize_bitmap = GART_IOMMU_PGSIZES, |
294 | .of_xlate = gart_iommu_of_xlate, | 300 | .of_xlate = gart_iommu_of_xlate, |
295 | .iotlb_sync_map = gart_iommu_sync, | 301 | .iotlb_sync_map = gart_iommu_sync_map, |
296 | .iotlb_sync = gart_iommu_sync, | 302 | .iotlb_sync = gart_iommu_sync, |
297 | }; | 303 | }; |
298 | 304 | ||
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index c4a652b227f8..7293fc3f796d 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c | |||
@@ -680,7 +680,7 @@ static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova, | |||
680 | } | 680 | } |
681 | 681 | ||
682 | static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova, | 682 | static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova, |
683 | size_t size) | 683 | size_t size, struct iommu_iotlb_gather *gather) |
684 | { | 684 | { |
685 | struct tegra_smmu_as *as = to_smmu_as(domain); | 685 | struct tegra_smmu_as *as = to_smmu_as(domain); |
686 | dma_addr_t pte_dma; | 686 | dma_addr_t pte_dma; |
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 433f4d2ee956..5f9f91a4d7f3 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c | |||
@@ -742,7 +742,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova, | |||
742 | } | 742 | } |
743 | 743 | ||
744 | static size_t viommu_unmap(struct iommu_domain *domain, unsigned long iova, | 744 | static size_t viommu_unmap(struct iommu_domain *domain, unsigned long iova, |
745 | size_t size) | 745 | size_t size, struct iommu_iotlb_gather *gather) |
746 | { | 746 | { |
747 | int ret = 0; | 747 | int ret = 0; |
748 | size_t unmapped; | 748 | size_t unmapped; |
@@ -788,7 +788,8 @@ static phys_addr_t viommu_iova_to_phys(struct iommu_domain *domain, | |||
788 | return paddr; | 788 | return paddr; |
789 | } | 789 | } |
790 | 790 | ||
791 | static void viommu_iotlb_sync(struct iommu_domain *domain) | 791 | static void viommu_iotlb_sync(struct iommu_domain *domain, |
792 | struct iommu_iotlb_gather *gather) | ||
792 | { | 793 | { |
793 | struct viommu_domain *vdomain = to_viommu_domain(domain); | 794 | struct viommu_domain *vdomain = to_viommu_domain(domain); |
794 | 795 | ||
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index ad41aee55bc6..64ebaff33455 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
@@ -258,10 +258,11 @@ struct iommu_ops { | |||
258 | int (*map)(struct iommu_domain *domain, unsigned long iova, | 258 | int (*map)(struct iommu_domain *domain, unsigned long iova, |
259 | phys_addr_t paddr, size_t size, int prot); | 259 | phys_addr_t paddr, size_t size, int prot); |
260 | size_t (*unmap)(struct iommu_domain *domain, unsigned long iova, | 260 | size_t (*unmap)(struct iommu_domain *domain, unsigned long iova, |
261 | size_t size); | 261 | size_t size, struct iommu_iotlb_gather *iotlb_gather); |
262 | void (*flush_iotlb_all)(struct iommu_domain *domain); | 262 | void (*flush_iotlb_all)(struct iommu_domain *domain); |
263 | void (*iotlb_sync_map)(struct iommu_domain *domain); | 263 | void (*iotlb_sync_map)(struct iommu_domain *domain); |
264 | void (*iotlb_sync)(struct iommu_domain *domain); | 264 | void (*iotlb_sync)(struct iommu_domain *domain, |
265 | struct iommu_iotlb_gather *iotlb_gather); | ||
265 | phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova); | 266 | phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova); |
266 | int (*add_device)(struct device *dev); | 267 | int (*add_device)(struct device *dev); |
267 | void (*remove_device)(struct device *dev); | 268 | void (*remove_device)(struct device *dev); |
@@ -502,7 +503,7 @@ static inline void iommu_tlb_sync(struct iommu_domain *domain, | |||
502 | struct iommu_iotlb_gather *iotlb_gather) | 503 | struct iommu_iotlb_gather *iotlb_gather) |
503 | { | 504 | { |
504 | if (domain->ops->iotlb_sync) | 505 | if (domain->ops->iotlb_sync) |
505 | domain->ops->iotlb_sync(domain); | 506 | domain->ops->iotlb_sync(domain, iotlb_gather); |
506 | 507 | ||
507 | iommu_iotlb_gather_init(iotlb_gather); | 508 | iommu_iotlb_gather_init(iotlb_gather); |
508 | } | 509 | } |