Skip to content

Commit 6f43bae

Browse files
committed
Merge tag 'dma-mapping-5.7' of git://git.infradead.org/users/hch/dma-mapping
Pull dma-mapping updates from Christoph Hellwig: - fix an integer overflow in the coherent pool (Kevin Grandemange) - provide support for in-place uncached remapping and use that for openrisc - fix the arm coherent allocator to take the bus limit into account * tag 'dma-mapping-5.7' of git://git.infradead.org/users/hch/dma-mapping: ARM/dma-mapping: merge __dma_supported into arm_dma_supported ARM/dma-mapping: take the bus limit into account in __dma_alloc ARM/dma-mapping: remove get_coherent_dma_mask openrisc: use the generic in-place uncached DMA allocator dma-direct: provide a arch_dma_clear_uncached hook dma-direct: make uncached_kernel_address more general dma-direct: consolidate the error handling in dma_direct_alloc_pages dma-direct: remove the cached_kernel_address hook dma-coherent: fix integer overflow in the reserved-memory dma allocation
2 parents 1e396a5 + fd27a52 commit 6f43bae

File tree

16 files changed

+76
-166
lines changed

16 files changed

+76
-166
lines changed

arch/Kconfig

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,18 @@ config ARCH_HAS_SET_DIRECT_MAP
248248
bool
249249

250250
#
251-
# Select if arch has an uncached kernel segment and provides the
252-
# uncached_kernel_address / cached_kernel_address symbols to use it
251+
# Select if the architecture provides the arch_dma_set_uncached symbol to
252+
# either provide an uncached segement alias for a DMA allocation, or
253+
# to remap the page tables in place.
253254
#
254-
config ARCH_HAS_UNCACHED_SEGMENT
255-
select ARCH_HAS_DMA_PREP_COHERENT
255+
config ARCH_HAS_DMA_SET_UNCACHED
256+
bool
257+
258+
#
259+
# Select if the architectures provides the arch_dma_clear_uncached symbol
260+
# to undo an in-place page table remap for uncached access.
261+
#
262+
config ARCH_HAS_DMA_CLEAR_UNCACHED
256263
bool
257264

258265
# Select if arch init_task must go in the __init_task_data section

arch/arm/include/asm/dma-iommu.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,5 @@ int arm_iommu_attach_device(struct device *dev,
3333
struct dma_iommu_mapping *mapping);
3434
void arm_iommu_detach_device(struct device *dev);
3535

36-
int arm_dma_supported(struct device *dev, u64 mask);
37-
3836
#endif /* __KERNEL__ */
3937
#endif

arch/arm/mm/dma-mapping.c

Lines changed: 18 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,23 @@ static void arm_dma_sync_single_for_device(struct device *dev,
179179
__dma_page_cpu_to_dev(page, offset, size, dir);
180180
}
181181

182+
/*
183+
* Return whether the given device DMA address mask can be supported
184+
* properly. For example, if your device can only drive the low 24-bits
185+
* during bus mastering, then you would pass 0x00ffffff as the mask
186+
* to this function.
187+
*/
188+
static int arm_dma_supported(struct device *dev, u64 mask)
189+
{
190+
unsigned long max_dma_pfn = min(max_pfn - 1, arm_dma_pfn_limit);
191+
192+
/*
193+
* Translate the device's DMA mask to a PFN limit. This
194+
* PFN number includes the page which we can DMA to.
195+
*/
196+
return dma_to_pfn(dev, mask) >= max_dma_pfn;
197+
}
198+
182199
const struct dma_map_ops arm_dma_ops = {
183200
.alloc = arm_dma_alloc,
184201
.free = arm_dma_free,
@@ -219,49 +236,6 @@ const struct dma_map_ops arm_coherent_dma_ops = {
219236
};
220237
EXPORT_SYMBOL(arm_coherent_dma_ops);
221238

222-
static int __dma_supported(struct device *dev, u64 mask, bool warn)
223-
{
224-
unsigned long max_dma_pfn = min(max_pfn - 1, arm_dma_pfn_limit);
225-
226-
/*
227-
* Translate the device's DMA mask to a PFN limit. This
228-
* PFN number includes the page which we can DMA to.
229-
*/
230-
if (dma_to_pfn(dev, mask) < max_dma_pfn) {
231-
if (warn)
232-
dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
233-
mask,
234-
dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
235-
max_dma_pfn + 1);
236-
return 0;
237-
}
238-
239-
return 1;
240-
}
241-
242-
static u64 get_coherent_dma_mask(struct device *dev)
243-
{
244-
u64 mask = (u64)DMA_BIT_MASK(32);
245-
246-
if (dev) {
247-
mask = dev->coherent_dma_mask;
248-
249-
/*
250-
* Sanity check the DMA mask - it must be non-zero, and
251-
* must be able to be satisfied by a DMA allocation.
252-
*/
253-
if (mask == 0) {
254-
dev_warn(dev, "coherent DMA mask is unset\n");
255-
return 0;
256-
}
257-
258-
if (!__dma_supported(dev, mask, true))
259-
return 0;
260-
}
261-
262-
return mask;
263-
}
264-
265239
static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag)
266240
{
267241
/*
@@ -688,7 +662,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
688662
gfp_t gfp, pgprot_t prot, bool is_coherent,
689663
unsigned long attrs, const void *caller)
690664
{
691-
u64 mask = get_coherent_dma_mask(dev);
665+
u64 mask = min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit);
692666
struct page *page = NULL;
693667
void *addr;
694668
bool allowblock, cma;
@@ -712,9 +686,6 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
712686
}
713687
#endif
714688

715-
if (!mask)
716-
return NULL;
717-
718689
buf = kzalloc(sizeof(*buf),
719690
gfp & ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM));
720691
if (!buf)
@@ -1087,17 +1058,6 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
10871058
dir);
10881059
}
10891060

1090-
/*
1091-
* Return whether the given device DMA address mask can be supported
1092-
* properly. For example, if your device can only drive the low 24-bits
1093-
* during bus mastering, then you would pass 0x00ffffff as the mask
1094-
* to this function.
1095-
*/
1096-
int arm_dma_supported(struct device *dev, u64 mask)
1097-
{
1098-
return __dma_supported(dev, mask, false);
1099-
}
1100-
11011061
static const struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
11021062
{
11031063
/*

arch/microblaze/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ config MICROBLAZE
88
select ARCH_HAS_GCOV_PROFILE_ALL
99
select ARCH_HAS_SYNC_DMA_FOR_CPU
1010
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
11-
select ARCH_HAS_UNCACHED_SEGMENT if !MMU
11+
select ARCH_HAS_DMA_SET_UNCACHED if !MMU
1212
select ARCH_MIGHT_HAVE_PC_PARPORT
1313
select ARCH_WANT_IPC_PARSE_VERSION
1414
select BUILDTIME_TABLE_SORT

arch/microblaze/mm/consistent.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
4040
#define UNCACHED_SHADOW_MASK 0
4141
#endif /* CONFIG_XILINX_UNCACHED_SHADOW */
4242

43-
void *uncached_kernel_address(void *ptr)
43+
void *arch_dma_set_uncached(void *ptr, size_t size)
4444
{
4545
unsigned long addr = (unsigned long)ptr;
4646

@@ -49,11 +49,4 @@ void *uncached_kernel_address(void *ptr)
4949
pr_warn("ERROR: Your cache coherent area is CACHED!!!\n");
5050
return (void *)addr;
5151
}
52-
53-
void *cached_kernel_address(void *ptr)
54-
{
55-
unsigned long addr = (unsigned long)ptr;
56-
57-
return (void *)(addr & ~UNCACHED_SHADOW_MASK);
58-
}
5952
#endif /* CONFIG_MMU */

arch/mips/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1192,8 +1192,9 @@ config DMA_NONCOHERENT
11921192
# significant advantages.
11931193
#
11941194
select ARCH_HAS_DMA_WRITE_COMBINE
1195+
select ARCH_HAS_DMA_PREP_COHERENT
11951196
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
1196-
select ARCH_HAS_UNCACHED_SEGMENT
1197+
select ARCH_HAS_DMA_SET_UNCACHED
11971198
select DMA_NONCOHERENT_MMAP
11981199
select DMA_NONCOHERENT_CACHE_SYNC
11991200
select NEED_DMA_MAP_STATE

arch/mips/mm/dma-noncoherent.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,11 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
4949
dma_cache_wback_inv((unsigned long)page_address(page), size);
5050
}
5151

52-
void *uncached_kernel_address(void *addr)
52+
void *arch_dma_set_uncached(void *addr, size_t size)
5353
{
5454
return (void *)(__pa(addr) + UNCAC_BASE);
5555
}
5656

57-
void *cached_kernel_address(void *addr)
58-
{
59-
return __va(addr) - UNCAC_BASE;
60-
}
61-
6257
static inline void dma_sync_virt(void *addr, size_t size,
6358
enum dma_data_direction dir)
6459
{

arch/nios2/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
config NIOS2
33
def_bool y
44
select ARCH_32BIT_OFF_T
5+
select ARCH_HAS_DMA_PREP_COHERENT
56
select ARCH_HAS_SYNC_DMA_FOR_CPU
67
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
7-
select ARCH_HAS_UNCACHED_SEGMENT
8+
select ARCH_HAS_DMA_SET_UNCACHED
89
select ARCH_NO_SWAP
910
select TIMER_OF
1011
select GENERIC_ATOMIC64

arch/nios2/mm/dma-mapping.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,11 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
6767
flush_dcache_range(start, start + size);
6868
}
6969

70-
void *uncached_kernel_address(void *ptr)
70+
void *arch_dma_set_uncached(void *ptr, size_t size)
7171
{
7272
unsigned long addr = (unsigned long)ptr;
7373

7474
addr |= CONFIG_NIOS2_IO_REGION_BASE;
7575

7676
return (void *)ptr;
7777
}
78-
79-
void *cached_kernel_address(void *ptr)
80-
{
81-
unsigned long addr = (unsigned long)ptr;
82-
83-
addr &= ~CONFIG_NIOS2_IO_REGION_BASE;
84-
addr |= CONFIG_NIOS2_KERNEL_REGION_BASE;
85-
86-
return (void *)ptr;
87-
}

arch/openrisc/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
config OPENRISC
88
def_bool y
99
select ARCH_32BIT_OFF_T
10+
select ARCH_HAS_DMA_SET_UNCACHED
11+
select ARCH_HAS_DMA_CLEAR_UNCACHED
1012
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
1113
select OF
1214
select OF_EARLY_FLATTREE

0 commit comments

Comments
 (0)