aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhen Lei <thunder.leizhen@huawei.com>2017-09-21 11:52:45 -0400
committerJoerg Roedel <jroedel@suse.de>2017-09-27 11:09:57 -0400
commitaa3ac9469c1850ed00741955b975c3a19029763a (patch)
tree998e22c451f149ef7c2cd5284d1539cc9b33496f
parente60aa7b53845a261dd419652f12ab9f89e668843 (diff)
iommu/iova: Make dma_32bit_pfn implicit
Now that the cached node optimisation can apply to all allocations, the couple of users which were playing tricks with dma_32bit_pfn in order to benefit from it can stop doing so. Conversely, there is also no need for all the other users to explicitly calculate a 'real' 32-bit PFN, when init_iova_domain() can happily do that itself from the page granularity. CC: Thierry Reding <thierry.reding@gmail.com> CC: Jonathan Hunter <jonathanh@nvidia.com> CC: David Airlie <airlied@linux.ie> CC: Sudeep Dutt <sudeep.dutt@intel.com> CC: Ashutosh Dixit <ashutosh.dixit@intel.com> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Tested-by: Zhen Lei <thunder.leizhen@huawei.com> Tested-by: Nate Watterson <nwatters@codeaurora.org> [rm: use iova_shift(), rewrote commit message] Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/gpu/drm/tegra/drm.c3
-rw-r--r--drivers/gpu/host1x/dev.c3
-rw-r--r--drivers/iommu/amd_iommu.c7
-rw-r--r--drivers/iommu/dma-iommu.c18
-rw-r--r--drivers/iommu/intel-iommu.c11
-rw-r--r--drivers/iommu/iova.c4
-rw-r--r--drivers/misc/mic/scif/scif_rma.c3
-rw-r--r--include/linux/iova.h5
8 files changed, 13 insertions, 41 deletions
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 597d563d636a..b822e484b7e5 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -155,8 +155,7 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
155 155
156 order = __ffs(tegra->domain->pgsize_bitmap); 156 order = __ffs(tegra->domain->pgsize_bitmap);
157 init_iova_domain(&tegra->carveout.domain, 1UL << order, 157 init_iova_domain(&tegra->carveout.domain, 1UL << order,
158 carveout_start >> order, 158 carveout_start >> order);
159 carveout_end >> order);
160 159
161 tegra->carveout.shift = iova_shift(&tegra->carveout.domain); 160 tegra->carveout.shift = iova_shift(&tegra->carveout.domain);
162 tegra->carveout.limit = carveout_end >> tegra->carveout.shift; 161 tegra->carveout.limit = carveout_end >> tegra->carveout.shift;
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 7f22c5c37660..5267c62e8896 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -198,8 +198,7 @@ static int host1x_probe(struct platform_device *pdev)
198 198
199 order = __ffs(host->domain->pgsize_bitmap); 199 order = __ffs(host->domain->pgsize_bitmap);
200 init_iova_domain(&host->iova, 1UL << order, 200 init_iova_domain(&host->iova, 1UL << order,
201 geometry->aperture_start >> order, 201 geometry->aperture_start >> order);
202 geometry->aperture_end >> order);
203 host->iova_end = geometry->aperture_end; 202 host->iova_end = geometry->aperture_end;
204 } 203 }
205 204
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 51f8215877f5..647ab7691aee 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -63,7 +63,6 @@
63/* IO virtual address start page frame number */ 63/* IO virtual address start page frame number */
64#define IOVA_START_PFN (1) 64#define IOVA_START_PFN (1)
65#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) 65#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
66#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))
67 66
68/* Reserved IOVA ranges */ 67/* Reserved IOVA ranges */
69#define MSI_RANGE_START (0xfee00000) 68#define MSI_RANGE_START (0xfee00000)
@@ -1788,8 +1787,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(void)
1788 if (!dma_dom->domain.pt_root) 1787 if (!dma_dom->domain.pt_root)
1789 goto free_dma_dom; 1788 goto free_dma_dom;
1790 1789
1791 init_iova_domain(&dma_dom->iovad, PAGE_SIZE, 1790 init_iova_domain(&dma_dom->iovad, PAGE_SIZE, IOVA_START_PFN);
1792 IOVA_START_PFN, DMA_32BIT_PFN);
1793 1791
1794 if (init_iova_flush_queue(&dma_dom->iovad, iova_domain_flush_tlb, NULL)) 1792 if (init_iova_flush_queue(&dma_dom->iovad, iova_domain_flush_tlb, NULL))
1795 goto free_dma_dom; 1793 goto free_dma_dom;
@@ -2696,8 +2694,7 @@ static int init_reserved_iova_ranges(void)
2696 struct pci_dev *pdev = NULL; 2694 struct pci_dev *pdev = NULL;
2697 struct iova *val; 2695 struct iova *val;
2698 2696
2699 init_iova_domain(&reserved_iova_ranges, PAGE_SIZE, 2697 init_iova_domain(&reserved_iova_ranges, PAGE_SIZE, IOVA_START_PFN);
2700 IOVA_START_PFN, DMA_32BIT_PFN);
2701 2698
2702 lockdep_set_class(&reserved_iova_ranges.iova_rbtree_lock, 2699 lockdep_set_class(&reserved_iova_ranges.iova_rbtree_lock,
2703 &reserved_rbtree_key); 2700 &reserved_rbtree_key);
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 9d1cebe7f6cb..191be9c80a8a 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -292,18 +292,7 @@ int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
292 /* ...then finally give it a kicking to make sure it fits */ 292 /* ...then finally give it a kicking to make sure it fits */
293 base_pfn = max_t(unsigned long, base_pfn, 293 base_pfn = max_t(unsigned long, base_pfn,
294 domain->geometry.aperture_start >> order); 294 domain->geometry.aperture_start >> order);
295 end_pfn = min_t(unsigned long, end_pfn,
296 domain->geometry.aperture_end >> order);
297 } 295 }
298 /*
299 * PCI devices may have larger DMA masks, but still prefer allocating
300 * within a 32-bit mask to avoid DAC addressing. Such limitations don't
301 * apply to the typical platform device, so for those we may as well
302 * leave the cache limit at the top of their range to save an rb_last()
303 * traversal on every allocation.
304 */
305 if (dev && dev_is_pci(dev))
306 end_pfn &= DMA_BIT_MASK(32) >> order;
307 296
308 /* start_pfn is always nonzero for an already-initialised domain */ 297 /* start_pfn is always nonzero for an already-initialised domain */
309 if (iovad->start_pfn) { 298 if (iovad->start_pfn) {
@@ -312,16 +301,11 @@ int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
312 pr_warn("Incompatible range for DMA domain\n"); 301 pr_warn("Incompatible range for DMA domain\n");
313 return -EFAULT; 302 return -EFAULT;
314 } 303 }
315 /*
316 * If we have devices with different DMA masks, move the free
317 * area cache limit down for the benefit of the smaller one.
318 */
319 iovad->dma_32bit_pfn = min(end_pfn + 1, iovad->dma_32bit_pfn);
320 304
321 return 0; 305 return 0;
322 } 306 }
323 307
324 init_iova_domain(iovad, 1UL << order, base_pfn, end_pfn); 308 init_iova_domain(iovad, 1UL << order, base_pfn);
325 if (!dev) 309 if (!dev)
326 return 0; 310 return 0;
327 311
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 6784a05dd6b2..ebb48353dd39 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -82,8 +82,6 @@
82#define IOVA_START_PFN (1) 82#define IOVA_START_PFN (1)
83 83
84#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) 84#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
85#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))
86#define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64))
87 85
88/* page table handling */ 86/* page table handling */
89#define LEVEL_STRIDE (9) 87#define LEVEL_STRIDE (9)
@@ -1878,8 +1876,7 @@ static int dmar_init_reserved_ranges(void)
1878 struct iova *iova; 1876 struct iova *iova;
1879 int i; 1877 int i;
1880 1878
1881 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN, 1879 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
1882 DMA_32BIT_PFN);
1883 1880
1884 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock, 1881 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1885 &reserved_rbtree_key); 1882 &reserved_rbtree_key);
@@ -1938,8 +1935,7 @@ static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1938 unsigned long sagaw; 1935 unsigned long sagaw;
1939 int err; 1936 int err;
1940 1937
1941 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN, 1938 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
1942 DMA_32BIT_PFN);
1943 1939
1944 err = init_iova_flush_queue(&domain->iovad, 1940 err = init_iova_flush_queue(&domain->iovad,
1945 iommu_flush_iova, iova_entry_free); 1941 iommu_flush_iova, iova_entry_free);
@@ -4897,8 +4893,7 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
4897{ 4893{
4898 int adjust_width; 4894 int adjust_width;
4899 4895
4900 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN, 4896 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
4901 DMA_32BIT_PFN);
4902 domain_reserve_special_ranges(domain); 4897 domain_reserve_special_ranges(domain);
4903 4898
4904 /* calculate AGAW */ 4899 /* calculate AGAW */
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index c6f5a22f8d20..65032e60a5d1 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -37,7 +37,7 @@ static void fq_flush_timeout(unsigned long data);
37 37
38void 38void
39init_iova_domain(struct iova_domain *iovad, unsigned long granule, 39init_iova_domain(struct iova_domain *iovad, unsigned long granule,
40 unsigned long start_pfn, unsigned long pfn_32bit) 40 unsigned long start_pfn)
41{ 41{
42 /* 42 /*
43 * IOVA granularity will normally be equal to the smallest 43 * IOVA granularity will normally be equal to the smallest
@@ -52,7 +52,7 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule,
52 iovad->cached32_node = NULL; 52 iovad->cached32_node = NULL;
53 iovad->granule = granule; 53 iovad->granule = granule;
54 iovad->start_pfn = start_pfn; 54 iovad->start_pfn = start_pfn;
55 iovad->dma_32bit_pfn = pfn_32bit + 1; 55 iovad->dma_32bit_pfn = 1UL << (32 - iova_shift(iovad));
56 iovad->flush_cb = NULL; 56 iovad->flush_cb = NULL;
57 iovad->fq = NULL; 57 iovad->fq = NULL;
58 init_iova_rcaches(iovad); 58 init_iova_rcaches(iovad);
diff --git a/drivers/misc/mic/scif/scif_rma.c b/drivers/misc/mic/scif/scif_rma.c
index 329727e00e97..c824329f7012 100644
--- a/drivers/misc/mic/scif/scif_rma.c
+++ b/drivers/misc/mic/scif/scif_rma.c
@@ -39,8 +39,7 @@ void scif_rma_ep_init(struct scif_endpt *ep)
39 struct scif_endpt_rma_info *rma = &ep->rma_info; 39 struct scif_endpt_rma_info *rma = &ep->rma_info;
40 40
41 mutex_init(&rma->rma_lock); 41 mutex_init(&rma->rma_lock);
42 init_iova_domain(&rma->iovad, PAGE_SIZE, SCIF_IOVA_START_PFN, 42 init_iova_domain(&rma->iovad, PAGE_SIZE, SCIF_IOVA_START_PFN);
43 SCIF_DMA_64BIT_PFN);
44 spin_lock_init(&rma->tc_lock); 43 spin_lock_init(&rma->tc_lock);
45 mutex_init(&rma->mmn_lock); 44 mutex_init(&rma->mmn_lock);
46 INIT_LIST_HEAD(&rma->reg_list); 45 INIT_LIST_HEAD(&rma->reg_list);
diff --git a/include/linux/iova.h b/include/linux/iova.h
index 69ea3e258ff2..953cfd20f152 100644
--- a/include/linux/iova.h
+++ b/include/linux/iova.h
@@ -154,7 +154,7 @@ struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
154 unsigned long pfn_hi); 154 unsigned long pfn_hi);
155void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); 155void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
156void init_iova_domain(struct iova_domain *iovad, unsigned long granule, 156void init_iova_domain(struct iova_domain *iovad, unsigned long granule,
157 unsigned long start_pfn, unsigned long pfn_32bit); 157 unsigned long start_pfn);
158int init_iova_flush_queue(struct iova_domain *iovad, 158int init_iova_flush_queue(struct iova_domain *iovad,
159 iova_flush_cb flush_cb, iova_entry_dtor entry_dtor); 159 iova_flush_cb flush_cb, iova_entry_dtor entry_dtor);
160struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); 160struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
@@ -230,8 +230,7 @@ static inline void copy_reserved_iova(struct iova_domain *from,
230 230
231static inline void init_iova_domain(struct iova_domain *iovad, 231static inline void init_iova_domain(struct iova_domain *iovad,
232 unsigned long granule, 232 unsigned long granule,
233 unsigned long start_pfn, 233 unsigned long start_pfn)
234 unsigned long pfn_32bit)
235{ 234{
236} 235}
237 236