diff options
author | Zhen Lei <thunder.leizhen@huawei.com> | 2017-09-21 11:52:45 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2017-09-27 11:09:57 -0400 |
commit | aa3ac9469c1850ed00741955b975c3a19029763a (patch) | |
tree | 998e22c451f149ef7c2cd5284d1539cc9b33496f | |
parent | e60aa7b53845a261dd419652f12ab9f89e668843 (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.c | 3 | ||||
-rw-r--r-- | drivers/gpu/host1x/dev.c | 3 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu.c | 7 | ||||
-rw-r--r-- | drivers/iommu/dma-iommu.c | 18 | ||||
-rw-r--r-- | drivers/iommu/intel-iommu.c | 11 | ||||
-rw-r--r-- | drivers/iommu/iova.c | 4 | ||||
-rw-r--r-- | drivers/misc/mic/scif/scif_rma.c | 3 | ||||
-rw-r--r-- | include/linux/iova.h | 5 |
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 | ||
38 | void | 38 | void |
39 | init_iova_domain(struct iova_domain *iovad, unsigned long granule, | 39 | init_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); |
155 | void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); | 155 | void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); |
156 | void init_iova_domain(struct iova_domain *iovad, unsigned long granule, | 156 | void init_iova_domain(struct iova_domain *iovad, unsigned long granule, |
157 | unsigned long start_pfn, unsigned long pfn_32bit); | 157 | unsigned long start_pfn); |
158 | int init_iova_flush_queue(struct iova_domain *iovad, | 158 | int 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); |
160 | struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); | 160 | struct 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 | ||
231 | static inline void init_iova_domain(struct iova_domain *iovad, | 231 | static 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 | ||