• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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