diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-15 15:36:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-15 15:36:31 -0400 |
commit | 3684b03d8e9a889eda94ee74421959a9d55e5e19 (patch) | |
tree | 668debfd1574240401237fd5f8ef77445124634f | |
parent | f2fa30a8b842920896f974010ac4011b8d697566 (diff) | |
parent | c987ff0d3cb37d7fe1ddaa370811dfd9f73643fa (diff) |
Merge tag 'iommu-fixes-v4.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU fixes from Joerg Roedel:
- Some functions defined in a header file for the mediatek driver were
not marked inline. Fix that oversight.
- Fix a potential crash in the ARM64 dma-mapping code when freeing a
partially initialized domain.
- Another fix for ARM64 dma-mapping to respect IOMMU mapping
constraints when allocating IOVA addresses.
* tag 'iommu-fixes-v4.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
iommu/dma: Respect IOMMU aperture when allocating
iommu/dma: Don't put uninitialised IOVA domains
iommu/mediatek: Mark static functions in headers inline
-rw-r--r-- | drivers/iommu/dma-iommu.c | 14 | ||||
-rw-r--r-- | drivers/iommu/mtk_iommu.h | 6 |
2 files changed, 12 insertions, 8 deletions
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 08a1e2f3690f..00c8a08d56e7 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c | |||
@@ -68,7 +68,8 @@ void iommu_put_dma_cookie(struct iommu_domain *domain) | |||
68 | if (!iovad) | 68 | if (!iovad) |
69 | return; | 69 | return; |
70 | 70 | ||
71 | put_iova_domain(iovad); | 71 | if (iovad->granule) |
72 | put_iova_domain(iovad); | ||
72 | kfree(iovad); | 73 | kfree(iovad); |
73 | domain->iova_cookie = NULL; | 74 | domain->iova_cookie = NULL; |
74 | } | 75 | } |
@@ -151,12 +152,15 @@ int dma_direction_to_prot(enum dma_data_direction dir, bool coherent) | |||
151 | } | 152 | } |
152 | } | 153 | } |
153 | 154 | ||
154 | static struct iova *__alloc_iova(struct iova_domain *iovad, size_t size, | 155 | static struct iova *__alloc_iova(struct iommu_domain *domain, size_t size, |
155 | dma_addr_t dma_limit) | 156 | dma_addr_t dma_limit) |
156 | { | 157 | { |
158 | struct iova_domain *iovad = domain->iova_cookie; | ||
157 | unsigned long shift = iova_shift(iovad); | 159 | unsigned long shift = iova_shift(iovad); |
158 | unsigned long length = iova_align(iovad, size) >> shift; | 160 | unsigned long length = iova_align(iovad, size) >> shift; |
159 | 161 | ||
162 | if (domain->geometry.force_aperture) | ||
163 | dma_limit = min(dma_limit, domain->geometry.aperture_end); | ||
160 | /* | 164 | /* |
161 | * Enforce size-alignment to be safe - there could perhaps be an | 165 | * Enforce size-alignment to be safe - there could perhaps be an |
162 | * attribute to control this per-device, or at least per-domain... | 166 | * attribute to control this per-device, or at least per-domain... |
@@ -314,7 +318,7 @@ struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp, | |||
314 | if (!pages) | 318 | if (!pages) |
315 | return NULL; | 319 | return NULL; |
316 | 320 | ||
317 | iova = __alloc_iova(iovad, size, dev->coherent_dma_mask); | 321 | iova = __alloc_iova(domain, size, dev->coherent_dma_mask); |
318 | if (!iova) | 322 | if (!iova) |
319 | goto out_free_pages; | 323 | goto out_free_pages; |
320 | 324 | ||
@@ -386,7 +390,7 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, | |||
386 | phys_addr_t phys = page_to_phys(page) + offset; | 390 | phys_addr_t phys = page_to_phys(page) + offset; |
387 | size_t iova_off = iova_offset(iovad, phys); | 391 | size_t iova_off = iova_offset(iovad, phys); |
388 | size_t len = iova_align(iovad, size + iova_off); | 392 | size_t len = iova_align(iovad, size + iova_off); |
389 | struct iova *iova = __alloc_iova(iovad, len, dma_get_mask(dev)); | 393 | struct iova *iova = __alloc_iova(domain, len, dma_get_mask(dev)); |
390 | 394 | ||
391 | if (!iova) | 395 | if (!iova) |
392 | return DMA_ERROR_CODE; | 396 | return DMA_ERROR_CODE; |
@@ -538,7 +542,7 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, | |||
538 | prev = s; | 542 | prev = s; |
539 | } | 543 | } |
540 | 544 | ||
541 | iova = __alloc_iova(iovad, iova_len, dma_get_mask(dev)); | 545 | iova = __alloc_iova(domain, iova_len, dma_get_mask(dev)); |
542 | if (!iova) | 546 | if (!iova) |
543 | goto out_restore_sg; | 547 | goto out_restore_sg; |
544 | 548 | ||
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h index 9ed0a8462ccf..3dab13b4a211 100644 --- a/drivers/iommu/mtk_iommu.h +++ b/drivers/iommu/mtk_iommu.h | |||
@@ -55,19 +55,19 @@ struct mtk_iommu_data { | |||
55 | bool enable_4GB; | 55 | bool enable_4GB; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | static int compare_of(struct device *dev, void *data) | 58 | static inline int compare_of(struct device *dev, void *data) |
59 | { | 59 | { |
60 | return dev->of_node == data; | 60 | return dev->of_node == data; |
61 | } | 61 | } |
62 | 62 | ||
63 | static int mtk_iommu_bind(struct device *dev) | 63 | static inline int mtk_iommu_bind(struct device *dev) |
64 | { | 64 | { |
65 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | 65 | struct mtk_iommu_data *data = dev_get_drvdata(dev); |
66 | 66 | ||
67 | return component_bind_all(dev, &data->smi_imu); | 67 | return component_bind_all(dev, &data->smi_imu); |
68 | } | 68 | } |
69 | 69 | ||
70 | static void mtk_iommu_unbind(struct device *dev) | 70 | static inline void mtk_iommu_unbind(struct device *dev) |
71 | { | 71 | { |
72 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | 72 | struct mtk_iommu_data *data = dev_get_drvdata(dev); |
73 | 73 | ||