aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-19 16:27:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-19 16:27:23 -0400
commit671df189537883f36cf9c7d4f9495bfac0f86627 (patch)
tree22e5f598ed1f5d9b2218d85d4426140f804d61e6 /arch/arm
parentc9fe5630dae1df2328d82042602e2c4d1add8d57 (diff)
parentc7d9eccb3c1e802c5cbb2a764eb0eb9807d9f12e (diff)
Merge tag 'dma-mapping-5.4' of git://git.infradead.org/users/hch/dma-mapping
Pull dma-mapping updates from Christoph Hellwig: - add dma-mapping and block layer helpers to take care of IOMMU merging for mmc plus subsequent fixups (Yoshihiro Shimoda) - rework handling of the pgprot bits for remapping (me) - take care of the dma direct infrastructure for swiotlb-xen (me) - improve the dma noncoherent remapping infrastructure (me) - better defaults for ->mmap, ->get_sgtable and ->get_required_mask (me) - cleanup mmaping of coherent DMA allocations (me) - various misc cleanups (Andy Shevchenko, me) * tag 'dma-mapping-5.4' of git://git.infradead.org/users/hch/dma-mapping: (41 commits) mmc: renesas_sdhi_internal_dmac: Add MMC_CAP2_MERGE_CAPABLE mmc: queue: Fix bigger segments usage arm64: use asm-generic/dma-mapping.h swiotlb-xen: merge xen_unmap_single into xen_swiotlb_unmap_page swiotlb-xen: simplify cache maintainance swiotlb-xen: use the same foreign page check everywhere swiotlb-xen: remove xen_swiotlb_dma_mmap and xen_swiotlb_dma_get_sgtable xen: remove the exports for xen_{create,destroy}_contiguous_region xen/arm: remove xen_dma_ops xen/arm: simplify dma_cache_maint xen/arm: use dev_is_dma_coherent xen/arm: consolidate page-coherent.h xen/arm: use dma-noncoherent.h calls for xen-swiotlb cache maintainance arm: remove wrappers for the generic dma remap helpers dma-mapping: introduce a dma_common_find_pages helper dma-mapping: always use VM_DMA_COHERENT for generic DMA remap vmalloc: lift the arm flag for coherent mappings to common code dma-mapping: provide a better default ->get_required_mask dma-mapping: remove the dma_declare_coherent_memory export remoteproc: don't allow modular build ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/include/asm/device.h3
-rw-r--r--arch/arm/include/asm/dma-mapping.h6
-rw-r--r--arch/arm/include/asm/pgtable-nommu.h1
-rw-r--r--arch/arm/include/asm/xen/page-coherent.h93
-rw-r--r--arch/arm/mm/dma-mapping-nommu.c5
-rw-r--r--arch/arm/mm/dma-mapping.c84
-rw-r--r--arch/arm/mm/mm.h3
-rw-r--r--arch/arm/xen/mm.c129
9 files changed, 55 insertions, 271 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2ae7f8adcac4..aa1d3b25e89f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -8,7 +8,7 @@ config ARM
8 select ARCH_HAS_DEBUG_VIRTUAL if MMU 8 select ARCH_HAS_DEBUG_VIRTUAL if MMU
9 select ARCH_HAS_DEVMEM_IS_ALLOWED 9 select ARCH_HAS_DEVMEM_IS_ALLOWED
10 select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB 10 select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB
11 select ARCH_HAS_DMA_MMAP_PGPROT if SWIOTLB 11 select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
12 select ARCH_HAS_ELF_RANDOMIZE 12 select ARCH_HAS_ELF_RANDOMIZE
13 select ARCH_HAS_FORTIFY_SOURCE 13 select ARCH_HAS_FORTIFY_SOURCE
14 select ARCH_HAS_KEEPINITRD 14 select ARCH_HAS_KEEPINITRD
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index f6955b55c544..c675bc0d5aa8 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -15,9 +15,6 @@ struct dev_archdata {
15#ifdef CONFIG_ARM_DMA_USE_IOMMU 15#ifdef CONFIG_ARM_DMA_USE_IOMMU
16 struct dma_iommu_mapping *mapping; 16 struct dma_iommu_mapping *mapping;
17#endif 17#endif
18#ifdef CONFIG_XEN
19 const struct dma_map_ops *dev_dma_ops;
20#endif
21 unsigned int dma_coherent:1; 18 unsigned int dma_coherent:1;
22 unsigned int dma_ops_setup:1; 19 unsigned int dma_ops_setup:1;
23}; 20};
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index dba9355e2484..bdd80ddbca34 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -91,12 +91,6 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
91} 91}
92#endif 92#endif
93 93
94/* do not use this function in a driver */
95static inline bool is_device_dma_coherent(struct device *dev)
96{
97 return dev->archdata.dma_coherent;
98}
99
100/** 94/**
101 * arm_dma_alloc - allocate consistent memory for DMA 95 * arm_dma_alloc - allocate consistent memory for DMA
102 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 96 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
index 0b1f6799a32e..d0de24f06724 100644
--- a/arch/arm/include/asm/pgtable-nommu.h
+++ b/arch/arm/include/asm/pgtable-nommu.h
@@ -62,7 +62,6 @@ typedef pte_t *pte_addr_t;
62 */ 62 */
63#define pgprot_noncached(prot) (prot) 63#define pgprot_noncached(prot) (prot)
64#define pgprot_writecombine(prot) (prot) 64#define pgprot_writecombine(prot) (prot)
65#define pgprot_dmacoherent(prot) (prot)
66#define pgprot_device(prot) (prot) 65#define pgprot_device(prot) (prot)
67 66
68 67
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index 2c403e7c782d..27e984977402 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -1,95 +1,2 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H
3#define _ASM_ARM_XEN_PAGE_COHERENT_H
4
5#include <linux/dma-mapping.h>
6#include <asm/page.h>
7#include <xen/arm/page-coherent.h> 2#include <xen/arm/page-coherent.h>
8
9static inline const struct dma_map_ops *xen_get_dma_ops(struct device *dev)
10{
11 if (dev && dev->archdata.dev_dma_ops)
12 return dev->archdata.dev_dma_ops;
13 return get_arch_dma_ops(NULL);
14}
15
16static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
17 dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
18{
19 return xen_get_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
20}
21
22static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
23 void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
24{
25 xen_get_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
26}
27
28static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
29 dma_addr_t dev_addr, unsigned long offset, size_t size,
30 enum dma_data_direction dir, unsigned long attrs)
31{
32 unsigned long page_pfn = page_to_xen_pfn(page);
33 unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
34 unsigned long compound_pages =
35 (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
36 bool local = (page_pfn <= dev_pfn) &&
37 (dev_pfn - page_pfn < compound_pages);
38
39 /*
40 * Dom0 is mapped 1:1, while the Linux page can span across
41 * multiple Xen pages, it's not possible for it to contain a
42 * mix of local and foreign Xen pages. So if the first xen_pfn
43 * == mfn the page is local otherwise it's a foreign page
44 * grant-mapped in dom0. If the page is local we can safely
45 * call the native dma_ops function, otherwise we call the xen
46 * specific function.
47 */
48 if (local)
49 xen_get_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
50 else
51 __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
52}
53
54static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
55 size_t size, enum dma_data_direction dir, unsigned long attrs)
56{
57 unsigned long pfn = PFN_DOWN(handle);
58 /*
59 * Dom0 is mapped 1:1, while the Linux page can be spanned accross
60 * multiple Xen page, it's not possible to have a mix of local and
61 * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
62 * foreign mfn will always return false. If the page is local we can
63 * safely call the native dma_ops function, otherwise we call the xen
64 * specific function.
65 */
66 if (pfn_valid(pfn)) {
67 if (xen_get_dma_ops(hwdev)->unmap_page)
68 xen_get_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
69 } else
70 __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
71}
72
73static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
74 dma_addr_t handle, size_t size, enum dma_data_direction dir)
75{
76 unsigned long pfn = PFN_DOWN(handle);
77 if (pfn_valid(pfn)) {
78 if (xen_get_dma_ops(hwdev)->sync_single_for_cpu)
79 xen_get_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
80 } else
81 __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
82}
83
84static inline void xen_dma_sync_single_for_device(struct device *hwdev,
85 dma_addr_t handle, size_t size, enum dma_data_direction dir)
86{
87 unsigned long pfn = PFN_DOWN(handle);
88 if (pfn_valid(pfn)) {
89 if (xen_get_dma_ops(hwdev)->sync_single_for_device)
90 xen_get_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
91 } else
92 __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
93}
94
95#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index 52b82559d99b..db9247898300 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -68,8 +68,9 @@ static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
68 68
69 if (dma_mmap_from_global_coherent(vma, cpu_addr, size, &ret)) 69 if (dma_mmap_from_global_coherent(vma, cpu_addr, size, &ret))
70 return ret; 70 return ret;
71 71 if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
72 return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size, attrs); 72 return ret;
73 return -ENXIO;
73} 74}
74 75
75 76
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index d42557ee69c2..7d042d5c43e3 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -14,6 +14,7 @@
14#include <linux/list.h> 14#include <linux/list.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/dma-direct.h>
17#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
18#include <linux/dma-noncoherent.h> 19#include <linux/dma-noncoherent.h>
19#include <linux/dma-contiguous.h> 20#include <linux/dma-contiguous.h>
@@ -35,6 +36,7 @@
35#include <asm/mach/map.h> 36#include <asm/mach/map.h>
36#include <asm/system_info.h> 37#include <asm/system_info.h>
37#include <asm/dma-contiguous.h> 38#include <asm/dma-contiguous.h>
39#include <xen/swiotlb-xen.h>
38 40
39#include "dma.h" 41#include "dma.h"
40#include "mm.h" 42#include "mm.h"
@@ -192,6 +194,7 @@ const struct dma_map_ops arm_dma_ops = {
192 .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu, 194 .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
193 .sync_sg_for_device = arm_dma_sync_sg_for_device, 195 .sync_sg_for_device = arm_dma_sync_sg_for_device,
194 .dma_supported = arm_dma_supported, 196 .dma_supported = arm_dma_supported,
197 .get_required_mask = dma_direct_get_required_mask,
195}; 198};
196EXPORT_SYMBOL(arm_dma_ops); 199EXPORT_SYMBOL(arm_dma_ops);
197 200
@@ -212,6 +215,7 @@ const struct dma_map_ops arm_coherent_dma_ops = {
212 .map_sg = arm_dma_map_sg, 215 .map_sg = arm_dma_map_sg,
213 .map_resource = dma_direct_map_resource, 216 .map_resource = dma_direct_map_resource,
214 .dma_supported = arm_dma_supported, 217 .dma_supported = arm_dma_supported,
218 .get_required_mask = dma_direct_get_required_mask,
215}; 219};
216EXPORT_SYMBOL(arm_coherent_dma_ops); 220EXPORT_SYMBOL(arm_coherent_dma_ops);
217 221
@@ -336,25 +340,6 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
336 pgprot_t prot, struct page **ret_page, 340 pgprot_t prot, struct page **ret_page,
337 const void *caller, bool want_vaddr); 341 const void *caller, bool want_vaddr);
338 342
339static void *
340__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
341 const void *caller)
342{
343 /*
344 * DMA allocation can be mapped to user space, so lets
345 * set VM_USERMAP flags too.
346 */
347 return dma_common_contiguous_remap(page, size,
348 VM_ARM_DMA_CONSISTENT | VM_USERMAP,
349 prot, caller);
350}
351
352static void __dma_free_remap(void *cpu_addr, size_t size)
353{
354 dma_common_free_remap(cpu_addr, size,
355 VM_ARM_DMA_CONSISTENT | VM_USERMAP);
356}
357
358#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K 343#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
359static struct gen_pool *atomic_pool __ro_after_init; 344static struct gen_pool *atomic_pool __ro_after_init;
360 345
@@ -510,7 +495,7 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
510 if (!want_vaddr) 495 if (!want_vaddr)
511 goto out; 496 goto out;
512 497
513 ptr = __dma_alloc_remap(page, size, gfp, prot, caller); 498 ptr = dma_common_contiguous_remap(page, size, prot, caller);
514 if (!ptr) { 499 if (!ptr) {
515 __dma_free_buffer(page, size); 500 __dma_free_buffer(page, size);
516 return NULL; 501 return NULL;
@@ -577,7 +562,7 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size,
577 goto out; 562 goto out;
578 563
579 if (PageHighMem(page)) { 564 if (PageHighMem(page)) {
580 ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller); 565 ptr = dma_common_contiguous_remap(page, size, prot, caller);
581 if (!ptr) { 566 if (!ptr) {
582 dma_release_from_contiguous(dev, page, count); 567 dma_release_from_contiguous(dev, page, count);
583 return NULL; 568 return NULL;
@@ -597,7 +582,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
597{ 582{
598 if (want_vaddr) { 583 if (want_vaddr) {
599 if (PageHighMem(page)) 584 if (PageHighMem(page))
600 __dma_free_remap(cpu_addr, size); 585 dma_common_free_remap(cpu_addr, size);
601 else 586 else
602 __dma_remap(page, size, PAGE_KERNEL); 587 __dma_remap(page, size, PAGE_KERNEL);
603 } 588 }
@@ -689,7 +674,7 @@ static void *remap_allocator_alloc(struct arm_dma_alloc_args *args,
689static void remap_allocator_free(struct arm_dma_free_args *args) 674static void remap_allocator_free(struct arm_dma_free_args *args)
690{ 675{
691 if (args->want_vaddr) 676 if (args->want_vaddr)
692 __dma_free_remap(args->cpu_addr, args->size); 677 dma_common_free_remap(args->cpu_addr, args->size);
693 678
694 __dma_free_buffer(args->page, args->size); 679 __dma_free_buffer(args->page, args->size);
695} 680}
@@ -877,17 +862,6 @@ static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_add
877 __arm_dma_free(dev, size, cpu_addr, handle, attrs, true); 862 __arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
878} 863}
879 864
880/*
881 * The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
882 * that the intention is to allow exporting memory allocated via the
883 * coherent DMA APIs through the dma_buf API, which only accepts a
884 * scattertable. This presents a couple of problems:
885 * 1. Not all memory allocated via the coherent DMA APIs is backed by
886 * a struct page
887 * 2. Passing coherent DMA memory into the streaming APIs is not allowed
888 * as we will try to flush the memory through a different alias to that
889 * actually being used (and the flushes are redundant.)
890 */
891int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt, 865int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
892 void *cpu_addr, dma_addr_t handle, size_t size, 866 void *cpu_addr, dma_addr_t handle, size_t size,
893 unsigned long attrs) 867 unsigned long attrs)
@@ -1132,10 +1106,6 @@ static const struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
1132 * 32-bit DMA. 1106 * 32-bit DMA.
1133 * Use the generic dma-direct / swiotlb ops code in that case, as that 1107 * Use the generic dma-direct / swiotlb ops code in that case, as that
1134 * handles bounce buffering for us. 1108 * handles bounce buffering for us.
1135 *
1136 * Note: this checks CONFIG_ARM_LPAE instead of CONFIG_SWIOTLB as the
1137 * latter is also selected by the Xen code, but that code for now relies
1138 * on non-NULL dev_dma_ops. To be cleaned up later.
1139 */ 1109 */
1140 if (IS_ENABLED(CONFIG_ARM_LPAE)) 1110 if (IS_ENABLED(CONFIG_ARM_LPAE))
1141 return NULL; 1111 return NULL;
@@ -1373,17 +1343,6 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages,
1373} 1343}
1374 1344
1375/* 1345/*
1376 * Create a CPU mapping for a specified pages
1377 */
1378static void *
1379__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot,
1380 const void *caller)
1381{
1382 return dma_common_pages_remap(pages, size,
1383 VM_ARM_DMA_CONSISTENT | VM_USERMAP, prot, caller);
1384}
1385
1386/*
1387 * Create a mapping in device IO address space for specified pages 1346 * Create a mapping in device IO address space for specified pages
1388 */ 1347 */
1389static dma_addr_t 1348static dma_addr_t
@@ -1455,18 +1414,13 @@ static struct page **__atomic_get_pages(void *addr)
1455 1414
1456static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs) 1415static struct page **__iommu_get_pages(void *cpu_addr, unsigned long attrs)
1457{ 1416{
1458 struct vm_struct *area;
1459
1460 if (__in_atomic_pool(cpu_addr, PAGE_SIZE)) 1417 if (__in_atomic_pool(cpu_addr, PAGE_SIZE))
1461 return __atomic_get_pages(cpu_addr); 1418 return __atomic_get_pages(cpu_addr);
1462 1419
1463 if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) 1420 if (attrs & DMA_ATTR_NO_KERNEL_MAPPING)
1464 return cpu_addr; 1421 return cpu_addr;
1465 1422
1466 area = find_vm_area(cpu_addr); 1423 return dma_common_find_pages(cpu_addr);
1467 if (area && (area->flags & VM_ARM_DMA_CONSISTENT))
1468 return area->pages;
1469 return NULL;
1470} 1424}
1471 1425
1472static void *__iommu_alloc_simple(struct device *dev, size_t size, gfp_t gfp, 1426static void *__iommu_alloc_simple(struct device *dev, size_t size, gfp_t gfp,
@@ -1539,7 +1493,7 @@ static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
1539 if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) 1493 if (attrs & DMA_ATTR_NO_KERNEL_MAPPING)
1540 return pages; 1494 return pages;
1541 1495
1542 addr = __iommu_alloc_remap(pages, size, gfp, prot, 1496 addr = dma_common_pages_remap(pages, size, prot,
1543 __builtin_return_address(0)); 1497 __builtin_return_address(0));
1544 if (!addr) 1498 if (!addr)
1545 goto err_mapping; 1499 goto err_mapping;
@@ -1622,10 +1576,8 @@ void __arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
1622 return; 1576 return;
1623 } 1577 }
1624 1578
1625 if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) == 0) { 1579 if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) == 0)
1626 dma_common_free_remap(cpu_addr, size, 1580 dma_common_free_remap(cpu_addr, size);
1627 VM_ARM_DMA_CONSISTENT | VM_USERMAP);
1628 }
1629 1581
1630 __iommu_remove_mapping(dev, handle, size); 1582 __iommu_remove_mapping(dev, handle, size);
1631 __iommu_free_buffer(dev, pages, size, attrs); 1583 __iommu_free_buffer(dev, pages, size, attrs);
@@ -2363,10 +2315,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
2363 set_dma_ops(dev, dma_ops); 2315 set_dma_ops(dev, dma_ops);
2364 2316
2365#ifdef CONFIG_XEN 2317#ifdef CONFIG_XEN
2366 if (xen_initial_domain()) { 2318 if (xen_initial_domain())
2367 dev->archdata.dev_dma_ops = dev->dma_ops; 2319 dev->dma_ops = &xen_swiotlb_dma_ops;
2368 dev->dma_ops = xen_dma_ops;
2369 }
2370#endif 2320#endif
2371 dev->archdata.dma_ops_setup = true; 2321 dev->archdata.dma_ops_setup = true;
2372} 2322}
@@ -2402,12 +2352,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
2402 return dma_to_pfn(dev, dma_addr); 2352 return dma_to_pfn(dev, dma_addr);
2403} 2353}
2404 2354
2405pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
2406 unsigned long attrs)
2407{
2408 return __get_dma_pgprot(attrs, prot);
2409}
2410
2411void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, 2355void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
2412 gfp_t gfp, unsigned long attrs) 2356 gfp_t gfp, unsigned long attrs)
2413{ 2357{
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 941356d95a67..88c121ac14b3 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -70,9 +70,6 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
70#define VM_ARM_MTYPE(mt) ((mt) << 20) 70#define VM_ARM_MTYPE(mt) ((mt) << 20)
71#define VM_ARM_MTYPE_MASK (0x1f << 20) 71#define VM_ARM_MTYPE_MASK (0x1f << 20)
72 72
73/* consistent regions used by dma_alloc_attrs() */
74#define VM_ARM_DMA_CONSISTENT 0x20000000
75
76 73
77struct static_vm { 74struct static_vm {
78 struct vm_struct vm; 75 struct vm_struct vm;
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index d33b77e9add3..2b2c208408bb 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-only 1// SPDX-License-Identifier: GPL-2.0-only
2#include <linux/cpu.h> 2#include <linux/cpu.h>
3#include <linux/dma-mapping.h> 3#include <linux/dma-noncoherent.h>
4#include <linux/gfp.h> 4#include <linux/gfp.h>
5#include <linux/highmem.h> 5#include <linux/highmem.h>
6#include <linux/export.h> 6#include <linux/export.h>
@@ -35,105 +35,56 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order)
35 return __get_free_pages(flags, order); 35 return __get_free_pages(flags, order);
36} 36}
37 37
38enum dma_cache_op {
39 DMA_UNMAP,
40 DMA_MAP,
41};
42static bool hypercall_cflush = false; 38static bool hypercall_cflush = false;
43 39
44/* functions called by SWIOTLB */ 40/* buffers in highmem or foreign pages cannot cross page boundaries */
45 41static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op)
46static void dma_cache_maint(dma_addr_t handle, unsigned long offset,
47 size_t size, enum dma_data_direction dir, enum dma_cache_op op)
48{ 42{
49 struct gnttab_cache_flush cflush; 43 struct gnttab_cache_flush cflush;
50 unsigned long xen_pfn;
51 size_t left = size;
52 44
53 xen_pfn = (handle >> XEN_PAGE_SHIFT) + offset / XEN_PAGE_SIZE; 45 cflush.a.dev_bus_addr = handle & XEN_PAGE_MASK;
54 offset %= XEN_PAGE_SIZE; 46 cflush.offset = xen_offset_in_page(handle);
47 cflush.op = op;
55 48
56 do { 49 do {
57 size_t len = left; 50 if (size + cflush.offset > XEN_PAGE_SIZE)
58 51 cflush.length = XEN_PAGE_SIZE - cflush.offset;
59 /* buffers in highmem or foreign pages cannot cross page 52 else
60 * boundaries */ 53 cflush.length = size;
61 if (len + offset > XEN_PAGE_SIZE)
62 len = XEN_PAGE_SIZE - offset;
63
64 cflush.op = 0;
65 cflush.a.dev_bus_addr = xen_pfn << XEN_PAGE_SHIFT;
66 cflush.offset = offset;
67 cflush.length = len;
68
69 if (op == DMA_UNMAP && dir != DMA_TO_DEVICE)
70 cflush.op = GNTTAB_CACHE_INVAL;
71 if (op == DMA_MAP) {
72 if (dir == DMA_FROM_DEVICE)
73 cflush.op = GNTTAB_CACHE_INVAL;
74 else
75 cflush.op = GNTTAB_CACHE_CLEAN;
76 }
77 if (cflush.op)
78 HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
79 54
80 offset = 0; 55 HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
81 xen_pfn++;
82 left -= len;
83 } while (left);
84}
85 56
86static void __xen_dma_page_dev_to_cpu(struct device *hwdev, dma_addr_t handle, 57 cflush.offset = 0;
87 size_t size, enum dma_data_direction dir) 58 cflush.a.dev_bus_addr += cflush.length;
88{ 59 size -= cflush.length;
89 dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_UNMAP); 60 } while (size);
90} 61}
91 62
92static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle, 63/*
93 size_t size, enum dma_data_direction dir) 64 * Dom0 is mapped 1:1, and while the Linux page can span across multiple Xen
65 * pages, it is not possible for it to contain a mix of local and foreign Xen
66 * pages. Calling pfn_valid on a foreign mfn will always return false, so if
67 * pfn_valid returns true the pages is local and we can use the native
68 * dma-direct functions, otherwise we call the Xen specific version.
69 */
70void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle,
71 phys_addr_t paddr, size_t size, enum dma_data_direction dir)
94{ 72{
95 dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_MAP); 73 if (pfn_valid(PFN_DOWN(handle)))
74 arch_sync_dma_for_cpu(dev, paddr, size, dir);
75 else if (dir != DMA_TO_DEVICE)
76 dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
96} 77}
97 78
98void __xen_dma_map_page(struct device *hwdev, struct page *page, 79void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle,
99 dma_addr_t dev_addr, unsigned long offset, size_t size, 80 phys_addr_t paddr, size_t size, enum dma_data_direction dir)
100 enum dma_data_direction dir, unsigned long attrs)
101{ 81{
102 if (is_device_dma_coherent(hwdev)) 82 if (pfn_valid(PFN_DOWN(handle)))
103 return; 83 arch_sync_dma_for_device(dev, paddr, size, dir);
104 if (attrs & DMA_ATTR_SKIP_CPU_SYNC) 84 else if (dir == DMA_FROM_DEVICE)
105 return; 85 dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
106 86 else
107 __xen_dma_page_cpu_to_dev(hwdev, dev_addr, size, dir); 87 dma_cache_maint(handle, size, GNTTAB_CACHE_CLEAN);
108}
109
110void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
111 size_t size, enum dma_data_direction dir,
112 unsigned long attrs)
113
114{
115 if (is_device_dma_coherent(hwdev))
116 return;
117 if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
118 return;
119
120 __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
121}
122
123void __xen_dma_sync_single_for_cpu(struct device *hwdev,
124 dma_addr_t handle, size_t size, enum dma_data_direction dir)
125{
126 if (is_device_dma_coherent(hwdev))
127 return;
128 __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
129}
130
131void __xen_dma_sync_single_for_device(struct device *hwdev,
132 dma_addr_t handle, size_t size, enum dma_data_direction dir)
133{
134 if (is_device_dma_coherent(hwdev))
135 return;
136 __xen_dma_page_cpu_to_dev(hwdev, handle, size, dir);
137} 88}
138 89
139bool xen_arch_need_swiotlb(struct device *dev, 90bool xen_arch_need_swiotlb(struct device *dev,
@@ -159,7 +110,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
159 * memory and we are not able to flush the cache. 110 * memory and we are not able to flush the cache.
160 */ 111 */
161 return (!hypercall_cflush && (xen_pfn != bfn) && 112 return (!hypercall_cflush && (xen_pfn != bfn) &&
162 !is_device_dma_coherent(dev)); 113 !dev_is_dma_coherent(dev));
163} 114}
164 115
165int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order, 116int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
@@ -173,16 +124,11 @@ int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
173 *dma_handle = pstart; 124 *dma_handle = pstart;
174 return 0; 125 return 0;
175} 126}
176EXPORT_SYMBOL_GPL(xen_create_contiguous_region);
177 127
178void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order) 128void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order)
179{ 129{
180 return; 130 return;
181} 131}
182EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
183
184const struct dma_map_ops *xen_dma_ops;
185EXPORT_SYMBOL(xen_dma_ops);
186 132
187int __init xen_mm_init(void) 133int __init xen_mm_init(void)
188{ 134{
@@ -190,7 +136,6 @@ int __init xen_mm_init(void)
190 if (!xen_initial_domain()) 136 if (!xen_initial_domain())
191 return 0; 137 return 0;
192 xen_swiotlb_init(1, false); 138 xen_swiotlb_init(1, false);
193 xen_dma_ops = &xen_swiotlb_dma_ops;
194 139
195 cflush.op = 0; 140 cflush.op = 0;
196 cflush.a.dev_bus_addr = 0; 141 cflush.a.dev_bus_addr = 0;