1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Support for uncached DMA mappings.
4 * Part of Cortex-A510 erratum 2454944 workaround.
5 *
6 * Copyright (C) 2022-2023 ARM Ltd.
7 * Author: Robin Murphy <robin.murphy@arm.com>
8 * Activating swiotlb + disabling lazy vunmap: Beata Michalska
9 */
10 #include <linux/dma-direct.h>
11 #include <linux/dma-map-ops.h>
12 #include <linux/iommu.h>
13 #include <linux/slab.h>
14 #include <linux/swiotlb.h>
15 #include <linux/vmalloc.h>
16 #include <asm/cacheflush.h>
17
18 /*
19 * Bits [58:55] of the translation table descriptor are being reserved
20 * by the architecture for software use purposes. With the assumption that
21 * those should not be used on linear map addresses (which is not without
22 * any guarantee though), those bits are being leveraged to trace potential
23 * cacheable aliases. This is still far from being perfect, to say at least:
24 * ... categorically the worst, but oh well, needs must...
25 */
26 #define REFCOUNT_INC BIT(55)
27 #define PTE_REFCOUNT(pte) (((pte) >> 55) & 0xf)
28
pte_set_nc(pte_t * ptep,unsigned long addr,void * data)29 static int pte_set_nc(pte_t *ptep, unsigned long addr, void *data)
30 {
31 pteval_t old_pte, new_pte, pte;
32 unsigned int refcount;
33
34 pte = pte_val(READ_ONCE(*ptep));
35 do {
36 /* Avoid racing against the transient invalid state */
37 old_pte = pte | PTE_VALID;
38 new_pte = old_pte + REFCOUNT_INC;
39 refcount = PTE_REFCOUNT(pte);
40 if (WARN_ON(refcount == 15))
41 return -EINVAL;
42 if (refcount == 0) {
43 new_pte &= ~(PTE_ATTRINDX_MASK | PTE_VALID);
44 new_pte |= PTE_ATTRINDX(MT_NORMAL_NC);
45 }
46 pte = cmpxchg_relaxed(&pte_val(*ptep), old_pte, new_pte);
47 } while (pte != old_pte);
48
49 *(unsigned int *)data = refcount;
50 if (refcount)
51 return 0;
52
53 flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
54 WRITE_ONCE(*ptep, __pte(new_pte | PTE_VALID));
55 return 0;
56 }
57
pte_clear_nc(pte_t * ptep,unsigned long addr,void * data)58 static int pte_clear_nc(pte_t *ptep, unsigned long addr, void *data)
59 {
60 pteval_t old_pte, new_pte, pte;
61 unsigned int refcount;
62
63 pte = pte_val(READ_ONCE(*ptep));
64 do {
65 old_pte = pte | PTE_VALID;
66 new_pte = old_pte - REFCOUNT_INC;
67 refcount = PTE_REFCOUNT(pte);
68 if (WARN_ON(refcount == 0))
69 return -EINVAL;
70 if (refcount == 1) {
71 new_pte &= ~(PTE_ATTRINDX_MASK | PTE_VALID);
72 new_pte |= PTE_ATTRINDX(MT_NORMAL_TAGGED);
73 }
74 pte = cmpxchg_relaxed(&pte_val(*ptep), old_pte, new_pte);
75 } while (pte != old_pte);
76
77 if (refcount > 1)
78 return 0;
79
80 flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
81 WRITE_ONCE(*ptep, __pte(new_pte | PTE_VALID));
82 return 0;
83 }
84
set_nc(void * addr,size_t size)85 static int set_nc(void *addr, size_t size)
86 {
87 unsigned int count;
88 int ret = apply_to_existing_page_range(&init_mm, (unsigned long)addr,
89 size, pte_set_nc, &count);
90
91 WARN_RATELIMIT(count == 0 && page_mapped(virt_to_page(addr)),
92 "changing linear mapping but cacheable aliases may still exist\n");
93 dsb(ishst);
94 isb();
95 __flush_dcache_area(addr, size);
96 return ret;
97 }
98
clear_nc(void * addr,size_t size)99 static int clear_nc(void *addr, size_t size)
100 {
101 int ret = apply_to_existing_page_range(&init_mm, (unsigned long)addr,
102 size, pte_clear_nc, NULL);
103 dsb(ishst);
104 isb();
105 __inval_dcache_area(addr, size);
106 return ret;
107 }
108
__arm64_noalias_map(struct device * dev,phys_addr_t phys,size_t size,enum dma_data_direction dir,unsigned long attrs,bool bounce)109 static phys_addr_t __arm64_noalias_map(struct device *dev, phys_addr_t phys,
110 size_t size, enum dma_data_direction dir,
111 unsigned long attrs, bool bounce)
112 {
113 bounce = bounce || (phys | size) & ~PAGE_MASK;
114 if (bounce) {
115 phys = swiotlb_tbl_map_single(dev, phys, size, PAGE_ALIGN(size),
116 dir, attrs);
117 if (phys == DMA_MAPPING_ERROR)
118 return DMA_MAPPING_ERROR;
119 }
120 if (set_nc(phys_to_virt(phys & PAGE_MASK), PAGE_ALIGN(size)))
121 goto out_unmap;
122
123 return phys;
124 out_unmap:
125 if (bounce)
126 swiotlb_tbl_unmap_single(dev, phys, size, PAGE_ALIGN(size), dir,
127 attrs | DMA_ATTR_SKIP_CPU_SYNC);
128 return DMA_MAPPING_ERROR;
129
130 }
131
__arm64_noalias_unmap(struct device * dev,phys_addr_t phys,size_t size,enum dma_data_direction dir,unsigned long attrs)132 static void __arm64_noalias_unmap(struct device *dev, phys_addr_t phys, size_t size,
133 enum dma_data_direction dir, unsigned long attrs)
134 {
135 clear_nc(phys_to_virt(phys & PAGE_MASK), PAGE_ALIGN(size));
136 if (is_swiotlb_buffer(phys))
137 swiotlb_tbl_unmap_single(dev, phys, size, PAGE_ALIGN(size), dir, attrs);
138 }
139
__arm64_noalias_sync_for_device(struct device * dev,phys_addr_t phys,size_t size,enum dma_data_direction dir)140 static void __arm64_noalias_sync_for_device(struct device *dev, phys_addr_t phys,
141 size_t size, enum dma_data_direction dir)
142 {
143 if (is_swiotlb_buffer(phys))
144 swiotlb_tbl_sync_single(dev, phys, size, dir, SYNC_FOR_DEVICE);
145 else
146 arch_sync_dma_for_device(phys, size, dir);
147 }
148
__arm64_noalias_sync_for_cpu(struct device * dev,phys_addr_t phys,size_t size,enum dma_data_direction dir)149 static void __arm64_noalias_sync_for_cpu(struct device *dev, phys_addr_t phys,
150 size_t size, enum dma_data_direction dir)
151 {
152 if (is_swiotlb_buffer(phys))
153 swiotlb_tbl_sync_single(dev, phys, size, dir, SYNC_FOR_CPU);
154 else
155 arch_sync_dma_for_cpu(phys, size, dir);
156 }
157
arm64_noalias_alloc(struct device * dev,size_t size,dma_addr_t * dma_addr,gfp_t gfp,unsigned long attrs)158 static void *arm64_noalias_alloc(struct device *dev, size_t size,
159 dma_addr_t *dma_addr, gfp_t gfp, unsigned long attrs)
160 {
161 struct page *page;
162 void *ret;
163
164 if (attrs & DMA_ATTR_NO_WARN)
165 gfp |= __GFP_NOWARN;
166
167 size = PAGE_ALIGN(size);
168 page = dma_direct_alloc_pages(dev, size, dma_addr, 0, gfp & ~__GFP_ZERO);
169 if (!page)
170 return NULL;
171
172 ret = page_address(page);
173 if (set_nc(ret, size)) {
174 dma_direct_free_pages(dev, size, page, *dma_addr, 0);
175 return NULL;
176 }
177 return ret;
178 }
179
arm64_noalias_free(struct device * dev,size_t size,void * cpu_addr,dma_addr_t dma_addr,unsigned long attrs)180 static void arm64_noalias_free(struct device *dev, size_t size, void *cpu_addr,
181 dma_addr_t dma_addr, unsigned long attrs)
182 {
183 size = PAGE_ALIGN(size);
184 clear_nc(cpu_addr, size);
185 dma_direct_free_pages(dev, size, virt_to_page(cpu_addr), dma_addr, 0);
186 }
187
arm64_noalias_map_page(struct device * dev,struct page * page,unsigned long offset,size_t size,enum dma_data_direction dir,unsigned long attrs)188 static dma_addr_t arm64_noalias_map_page(struct device *dev, struct page *page,
189 unsigned long offset, size_t size,
190 enum dma_data_direction dir, unsigned long attrs)
191 {
192 phys_addr_t phys = page_to_phys(page) + offset;
193 bool bounce = !dma_capable(dev, phys_to_dma(dev, phys), size, true);
194
195 if (!bounce && dir == DMA_TO_DEVICE) {
196 arch_sync_dma_for_device(phys, size, dir);
197 return phys_to_dma(dev, phys);
198 }
199
200 bounce = bounce || page_mapped(page);
201 phys = __arm64_noalias_map(dev, phys, size, dir, attrs, bounce);
202 if (phys == DMA_MAPPING_ERROR)
203 return DMA_MAPPING_ERROR;
204
205 return phys_to_dma(dev, phys);
206 }
207
arm64_noalias_unmap_page(struct device * dev,dma_addr_t dma_addr,size_t size,enum dma_data_direction dir,unsigned long attrs)208 static void arm64_noalias_unmap_page(struct device *dev, dma_addr_t dma_addr,
209 size_t size, enum dma_data_direction dir,
210 unsigned long attrs)
211 {
212 if (dir == DMA_TO_DEVICE)
213 return;
214 __arm64_noalias_unmap(dev, dma_to_phys(dev, dma_addr), size, dir, attrs);
215 }
216
arm64_noalias_unmap_sg(struct device * dev,struct scatterlist * sgl,int nents,enum dma_data_direction dir,unsigned long attrs)217 static void arm64_noalias_unmap_sg(struct device *dev, struct scatterlist *sgl, int nents,
218 enum dma_data_direction dir, unsigned long attrs)
219 {
220 struct scatterlist *sg;
221 int i;
222
223 if (dir == DMA_TO_DEVICE)
224 return;
225 for_each_sg(sgl, sg, nents, i)
226 __arm64_noalias_unmap(dev, dma_to_phys(dev, sg->dma_address),
227 sg->length, dir, attrs);
228 }
229
arm64_noalias_map_sg(struct device * dev,struct scatterlist * sgl,int nents,enum dma_data_direction dir,unsigned long attrs)230 static int arm64_noalias_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
231 enum dma_data_direction dir, unsigned long attrs)
232 {
233 int i;
234 struct scatterlist *sg;
235
236 for_each_sg(sgl, sg, nents, i) {
237 sg->dma_address = arm64_noalias_map_page(dev, sg_page(sg), sg->offset,
238 sg->length, dir, attrs);
239 if (sg->dma_address == DMA_MAPPING_ERROR)
240 goto out_unmap;
241 sg->dma_length = sg->length;
242 }
243
244 return nents;
245
246 out_unmap:
247 arm64_noalias_unmap_sg(dev, sgl, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
248 return 0;
249 }
250
arm64_noalias_sync_single_for_device(struct device * dev,dma_addr_t addr,size_t size,enum dma_data_direction dir)251 static void arm64_noalias_sync_single_for_device(struct device *dev, dma_addr_t addr,
252 size_t size, enum dma_data_direction dir)
253 {
254 __arm64_noalias_sync_for_device(dev, dma_to_phys(dev, addr), size, dir);
255 }
256
arm64_noalias_sync_single_for_cpu(struct device * dev,dma_addr_t addr,size_t size,enum dma_data_direction dir)257 static void arm64_noalias_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
258 size_t size, enum dma_data_direction dir)
259 {
260 __arm64_noalias_sync_for_cpu(dev, dma_to_phys(dev, addr), size, dir);
261 }
262
arm64_noalias_sync_sg_for_device(struct device * dev,struct scatterlist * sgl,int nents,enum dma_data_direction dir)263 static void arm64_noalias_sync_sg_for_device(struct device *dev, struct scatterlist *sgl,
264 int nents, enum dma_data_direction dir)
265 {
266 struct scatterlist *sg;
267 int i;
268
269 for_each_sg(sgl, sg, nents, i)
270 arm64_noalias_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
271 }
272
arm64_noalias_sync_sg_for_cpu(struct device * dev,struct scatterlist * sgl,int nents,enum dma_data_direction dir)273 static void arm64_noalias_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl,
274 int nents, enum dma_data_direction dir)
275 {
276 struct scatterlist *sg;
277 int i;
278
279 for_each_sg(sgl, sg, nents, i)
280 arm64_noalias_sync_single_for_cpu(dev, sg->dma_address, sg->length, dir);
281 }
282
283 static const struct dma_map_ops arm64_noalias_ops = {
284 .alloc = arm64_noalias_alloc,
285 .free = arm64_noalias_free,
286 .alloc_pages = dma_common_alloc_pages,
287 .free_pages = dma_common_free_pages,
288 .mmap = dma_common_mmap,
289 .get_sgtable = dma_common_get_sgtable,
290 .map_page = arm64_noalias_map_page,
291 .unmap_page = arm64_noalias_unmap_page,
292 .map_sg = arm64_noalias_map_sg,
293 .unmap_sg = arm64_noalias_unmap_sg,
294 .sync_single_for_cpu = arm64_noalias_sync_single_for_cpu,
295 .sync_single_for_device = arm64_noalias_sync_single_for_device,
296 .sync_sg_for_cpu = arm64_noalias_sync_sg_for_cpu,
297 .sync_sg_for_device = arm64_noalias_sync_sg_for_device,
298 .dma_supported = dma_direct_supported,
299 .get_required_mask = dma_direct_get_required_mask,
300 .max_mapping_size = swiotlb_max_mapping_size,
301 };
302
303 #ifdef CONFIG_IOMMU_DMA
304 static const struct dma_map_ops *iommu_dma_ops;
305
arm64_iommu_alloc(struct device * dev,size_t size,dma_addr_t * dma_addr,gfp_t gfp,unsigned long attrs)306 static void *arm64_iommu_alloc(struct device *dev, size_t size,
307 dma_addr_t *dma_addr, gfp_t gfp, unsigned long attrs)
308 {
309 struct page **pages;
310 void *ret;
311 int i;
312
313 size = PAGE_ALIGN(size);
314 if (!gfpflags_allow_blocking(gfp) || (attrs & DMA_ATTR_FORCE_CONTIGUOUS)) {
315 ret = dma_common_alloc_pages(dev, size, dma_addr, 0, gfp);
316 return ret ? page_address(ret) : NULL;
317 }
318
319 ret = iommu_dma_ops->alloc(dev, size, dma_addr, gfp, attrs);
320 if (ret) {
321 pages = dma_common_find_pages(ret);
322 for (i = 0; i < size / PAGE_SIZE; i++)
323 if (set_nc(page_address(pages[i]), PAGE_SIZE))
324 goto err;
325 }
326 return ret;
327
328 err:
329 while (i--)
330 clear_nc(page_address(pages[i]), PAGE_SIZE);
331 iommu_dma_ops->free(dev, size, ret, *dma_addr, attrs);
332 return NULL;
333 }
334
arm64_iommu_free(struct device * dev,size_t size,void * cpu_addr,dma_addr_t dma_addr,unsigned long attrs)335 static void arm64_iommu_free(struct device *dev, size_t size, void *cpu_addr,
336 dma_addr_t dma_addr, unsigned long attrs)
337 {
338 struct page **pages = dma_common_find_pages(cpu_addr);
339 int i;
340
341 size = PAGE_ALIGN(size);
342 if (!pages)
343 return dma_common_free_pages(dev, size, virt_to_page(cpu_addr), dma_addr, 0);
344
345 for (i = 0; i < size / PAGE_SIZE; i++)
346 clear_nc(page_address(pages[i]), PAGE_SIZE);
347 iommu_dma_ops->free(dev, size, cpu_addr, dma_addr, attrs);
348 }
349
arm64_iommu_map_page(struct device * dev,struct page * page,unsigned long offset,size_t size,enum dma_data_direction dir,unsigned long attrs)350 static dma_addr_t arm64_iommu_map_page(struct device *dev, struct page *page,
351 unsigned long offset, size_t size,
352 enum dma_data_direction dir, unsigned long attrs)
353 {
354 phys_addr_t phys = page_to_phys(page) + offset;
355 dma_addr_t ret;
356
357 if (dir == DMA_TO_DEVICE)
358 return iommu_dma_ops->map_page(dev, page, offset, size, dir, attrs);
359
360 phys = __arm64_noalias_map(dev, phys, size, dir, attrs, page_mapped(page));
361 if (phys == DMA_MAPPING_ERROR)
362 return DMA_MAPPING_ERROR;
363
364 attrs |= DMA_ATTR_SKIP_CPU_SYNC;
365 ret = iommu_dma_ops->map_page(dev, phys_to_page(phys), offset_in_page(phys),
366 size, dir, attrs);
367 if (ret == DMA_MAPPING_ERROR)
368 __arm64_noalias_unmap(dev, phys, size, dir, attrs);
369 return ret;
370 }
371
arm64_iommu_unmap_page(struct device * dev,dma_addr_t addr,size_t size,enum dma_data_direction dir,unsigned long attrs)372 static void arm64_iommu_unmap_page(struct device *dev, dma_addr_t addr, size_t size,
373 enum dma_data_direction dir, unsigned long attrs)
374 {
375 phys_addr_t phys;
376
377 if (dir == DMA_TO_DEVICE)
378 return iommu_dma_ops->unmap_page(dev, addr, size, dir, attrs);
379
380 phys = iommu_iova_to_phys(iommu_get_dma_domain(dev), addr);
381 iommu_dma_ops->unmap_page(dev, addr, size, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
382 __arm64_noalias_unmap(dev, phys, size, dir, attrs);
383 }
384
arm64_iommu_map_sg(struct device * dev,struct scatterlist * sgl,int nents,enum dma_data_direction dir,unsigned long attrs)385 static int arm64_iommu_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
386 enum dma_data_direction dir, unsigned long attrs)
387 {
388 int i, ret;
389 struct scatterlist *sg;
390 phys_addr_t *orig_phys;
391
392 if (dir == DMA_TO_DEVICE)
393 return iommu_dma_ops->map_sg(dev, sgl, nents, dir, attrs);
394
395 orig_phys = kmalloc_array(nents, sizeof(*orig_phys), GFP_ATOMIC);
396 if (!orig_phys)
397 return 0;
398
399 for_each_sg(sgl, sg, nents, i) {
400 phys_addr_t phys = sg_phys(sg);
401 /*
402 * Note we do not have the page_mapped() check here, since
403 * bouncing plays complete havoc with dma-buf imports. Those
404 * may well be mapped in userspace, but we hope and pray that
405 * it's via dma_mmap_attrs() so any such mappings are safely
406 * non-cacheable. DO NOT allow a block device or other similar
407 * scatterlist user to get here (disable IOMMUs if necessary),
408 * since we can't mitigate for both conflicting use-cases.
409 */
410 phys = __arm64_noalias_map(dev, phys, sg->length, dir, attrs, false);
411 if (phys == DMA_MAPPING_ERROR)
412 goto out_unmap;
413
414 orig_phys[i] = sg_phys(sg);
415 sg_assign_page(sg, phys_to_page(phys));
416 sg->offset = offset_in_page(phys);
417 }
418 ret = iommu_dma_ops->map_sg(dev, sgl, nents, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
419 if (ret <= 0)
420 goto out_unmap;
421
422 for_each_sg(sgl, sg, nents, i) {
423 sg_assign_page(sg, phys_to_page(orig_phys[i]));
424 sg->offset = offset_in_page(orig_phys[i]);
425 }
426
427 kfree(orig_phys);
428 return ret;
429
430 out_unmap:
431 for_each_sg(sgl, sg, nents, i) {
432 __arm64_noalias_unmap(dev, sg_phys(sg), sg->length, dir, attrs);
433 sg_assign_page(sg, phys_to_page(orig_phys[i]));
434 sg->offset = offset_in_page(orig_phys[i]);
435 }
436 kfree(orig_phys);
437 return 0;
438 }
439
arm64_iommu_unmap_sg(struct device * dev,struct scatterlist * sgl,int nents,enum dma_data_direction dir,unsigned long attrs)440 static void arm64_iommu_unmap_sg(struct device *dev, struct scatterlist *sgl, int nents,
441 enum dma_data_direction dir, unsigned long attrs)
442 {
443 struct iommu_domain *domain;
444 struct scatterlist *sg, *tmp;
445 dma_addr_t iova;
446 int i;
447
448 if (dir == DMA_TO_DEVICE)
449 return iommu_dma_ops->unmap_sg(dev, sgl, nents, dir, attrs);
450
451 domain = iommu_get_dma_domain(dev);
452 iova = sgl->dma_address;
453 tmp = sgl;
454 for_each_sg(sgl, sg, nents, i) {
455 phys_addr_t phys = iommu_iova_to_phys(domain, iova);
456
457 __arm64_noalias_unmap(dev, phys, sg->length, dir, attrs);
458 iova += sg->length;
459 if (iova == tmp->dma_address + tmp->dma_length && !sg_is_last(tmp)) {
460 tmp = sg_next(tmp);
461 iova = tmp->dma_address;
462 }
463 }
464 iommu_dma_ops->unmap_sg(dev, sgl, nents, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
465 }
466
arm64_iommu_sync_single_for_device(struct device * dev,dma_addr_t addr,size_t size,enum dma_data_direction dir)467 static void arm64_iommu_sync_single_for_device(struct device *dev, dma_addr_t addr,
468 size_t size, enum dma_data_direction dir)
469 {
470 phys_addr_t phys = iommu_iova_to_phys(iommu_get_dma_domain(dev), addr);
471
472 __arm64_noalias_sync_for_device(dev, phys, size, dir);
473 }
474
arm64_iommu_sync_single_for_cpu(struct device * dev,dma_addr_t addr,size_t size,enum dma_data_direction dir)475 static void arm64_iommu_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
476 size_t size, enum dma_data_direction dir)
477 {
478 phys_addr_t phys = iommu_iova_to_phys(iommu_get_dma_domain(dev), addr);
479
480 __arm64_noalias_sync_for_cpu(dev, phys, size, dir);
481 }
482
arm64_iommu_sync_sg_for_device(struct device * dev,struct scatterlist * sgl,int nents,enum dma_data_direction dir)483 static void arm64_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sgl,
484 int nents, enum dma_data_direction dir)
485 {
486 struct iommu_domain *domain = iommu_get_dma_domain(dev);
487 struct scatterlist *sg, *tmp = sgl;
488 dma_addr_t iova = sgl->dma_address;
489 int i;
490
491 for_each_sg(sgl, sg, nents, i) {
492 phys_addr_t phys = iommu_iova_to_phys(domain, iova);
493
494 __arm64_noalias_sync_for_device(dev, phys, sg->length, dir);
495 iova += sg->length;
496 if (iova == tmp->dma_address + tmp->dma_length && !sg_is_last(tmp)) {
497 tmp = sg_next(tmp);
498 iova = tmp->dma_address;
499 }
500 }
501 }
502
arm64_iommu_sync_sg_for_cpu(struct device * dev,struct scatterlist * sgl,int nents,enum dma_data_direction dir)503 static void arm64_iommu_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl,
504 int nents, enum dma_data_direction dir)
505 {
506 struct iommu_domain *domain = iommu_get_dma_domain(dev);
507 struct scatterlist *sg, *tmp = sgl;
508 dma_addr_t iova = sgl->dma_address;
509 int i;
510
511 for_each_sg(sgl, sg, nents, i) {
512 phys_addr_t phys = iommu_iova_to_phys(domain, iova);
513
514 __arm64_noalias_sync_for_cpu(dev, phys, sg->length, dir);
515 iova += sg->length;
516 if (iova == tmp->dma_address + tmp->dma_length && !sg_is_last(tmp)) {
517 tmp = sg_next(tmp);
518 iova = tmp->dma_address;
519 }
520 }
521 }
522
523 static struct dma_map_ops arm64_iommu_ops = {
524 .alloc = arm64_iommu_alloc,
525 .free = arm64_iommu_free,
526 .alloc_pages = dma_common_alloc_pages,
527 .free_pages = dma_common_free_pages,
528 .map_page = arm64_iommu_map_page,
529 .unmap_page = arm64_iommu_unmap_page,
530 .map_sg = arm64_iommu_map_sg,
531 .unmap_sg = arm64_iommu_unmap_sg,
532 .sync_single_for_cpu = arm64_iommu_sync_single_for_cpu,
533 .sync_single_for_device = arm64_iommu_sync_single_for_device,
534 .sync_sg_for_cpu = arm64_iommu_sync_sg_for_cpu,
535 .sync_sg_for_device = arm64_iommu_sync_sg_for_device,
536 };
537
538 #endif /* CONFIG_IOMMU_DMA */
539
arm64_noalias_prepare(void)540 static inline void arm64_noalias_prepare(void)
541 {
542 if (!is_swiotlb_active())
543 swiotlb_late_init_with_default_size(swiotlb_size_or_default());
544 if (lazy_vunmap_enable) {
545 lazy_vunmap_enable = false;
546 vm_unmap_aliases();
547 }
548 }
549
arm64_noalias_setup_dma_ops(struct device * dev)550 void arm64_noalias_setup_dma_ops(struct device *dev)
551 {
552 if (dev_is_dma_coherent(dev))
553 return;
554
555 dev_info(dev, "applying no-alias DMA workaround\n");
556 if (!dev->dma_ops) {
557 dev->dma_ops = &arm64_noalias_ops;
558 goto done;
559 }
560
561 if (IS_ENABLED(CONFIG_IOMMU_DMA)) {
562 dev->dma_ops = &arm64_iommu_ops;
563 if (iommu_dma_ops)
564 goto done;
565
566 iommu_dma_ops = dev->dma_ops;
567 arm64_iommu_ops.mmap = iommu_dma_ops->mmap;
568 arm64_iommu_ops.get_sgtable = iommu_dma_ops->get_sgtable;
569 arm64_iommu_ops.map_resource = iommu_dma_ops->map_resource;
570 arm64_iommu_ops.unmap_resource = iommu_dma_ops->unmap_resource;
571 arm64_iommu_ops.get_merge_boundary = iommu_dma_ops->get_merge_boundary;
572 }
573 done:
574 arm64_noalias_prepare();
575 }
576 EXPORT_SYMBOL_GPL(arm64_noalias_setup_dma_ops);
577