Skip to contentSkip to conversation

consolidate direct dma mapping and swiotlb support

PATCH In review Christoph Hellwig 8 participants 176 messages Dec 29, 2017 – Jan 9, 2018 Page 1 of 2

Subsystems (41)
Networking Arm (32-bit) x86 SCSI +37 more subsystems
lore
Share & tools
lore
#0 lore raw

Almost every architecture supports a direct dma mapping implementation, where no iommu is used and the device dma address is a 1:1 mapping to the physical address or has a simple linear offset. Currently the code for this implementation is most duplicated over the architectures, and the duplicated again in the swiotlb code, and then duplicated again for special cases like the x86 memory encryption DMA ops.

This series takes the existing very simple dma-noop dma mapping implementation, enhances it with all the x86 features and quirks, and creates a common set of architecture hooks for it and the swiotlb code.

It then switches a large number of architectures to this generic direct map implement and the new generic swiotlb dma_map ops.

Note that for now this only handles architectures that do cache coherent DMA, but a similar consolidation for non-coherent architectures is in the work for later merge windows.

#1 lore raw

PATCH 1/67 x86: remove X86_PPRO_FENCE

There were only a few Pentium Pro multiprocessors systems where this errata applied. They are more than 20 years old now, and we've slowly dropped places where put the workarounds in and discuraged anyone from enabling the workaround.

Get rid of it for good.

---
 arch/x86/Kconfig.cpu                        | 13 -------------
 arch/x86/entry/vdso/vdso32/vclock_gettime.c |  2 --
 arch/x86/include/asm/barrier.h              | 30 -----------------------------
 arch/x86/include/asm/io.h                   | 15 ---------------
 arch/x86/kernel/pci-nommu.c                 | 19 ------------------
 arch/x86/um/asm/barrier.h                   |  4 ----
 6 files changed, 83 deletions(-)
arch/x86/Kconfig.cpu +0 -13
index 65a9a4716e34..f0c5ef578153 100644
@@ -315,19 +315,6 @@ config X86_L1_CACHE_SHIFT
 	default "4" if MELAN || M486 || MGEODEGX1
 	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
 
-config X86_PPRO_FENCE
-	bool "PentiumPro memory ordering errata workaround"
-	depends on M686 || M586MMX || M586TSC || M586 || M486 || MGEODEGX1
-	---help---
-	  Old PentiumPro multiprocessor systems had errata that could cause
-	  memory operations to violate the x86 ordering standard in rare cases.
-	  Enabling this option will attempt to work around some (but not all)
-	  occurrences of this problem, at the cost of much heavier spinlock and
-	  memory barrier operations.
-
-	  If unsure, say n here. Even distro kernels should think twice before
-	  enabling this: there are few systems, and an unlikely bug.
-
 config X86_F00F_BUG
 	def_bool y
 	depends on M586MMX || M586TSC || M586 || M486
arch/x86/entry/vdso/vdso32/vclock_gettime.c +0 -2
index 7780bbfb06ef..9242b28418d5 100644
@@ -5,8 +5,6 @@
 #undef CONFIG_OPTIMIZE_INLINING
 #endif
 
-#undef CONFIG_X86_PPRO_FENCE
-
 #ifdef CONFIG_X86_64
 
 /*
arch/x86/include/asm/barrier.h +0 -30
index 7fb336210e1b..aa0f7449d4a4 100644
@@ -24,11 +24,7 @@
 #define wmb()	asm volatile("sfence" ::: "memory")
 #endif
 
-#ifdef CONFIG_X86_PPRO_FENCE
-#define dma_rmb()	rmb()
-#else
 #define dma_rmb()	barrier()
-#endif
 #define dma_wmb()	barrier()
 
 #ifdef CONFIG_X86_32
@@ -40,30 +36,6 @@
 #define __smp_wmb()	barrier()
 #define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
 
-#if defined(CONFIG_X86_PPRO_FENCE)
-
-/*
- * For this option x86 doesn't have a strong TSO memory
- * model and we should fall back to full barriers.
- */
-
-#define __smp_store_release(p, v)					\
-do {									\
-	compiletime_assert_atomic_type(*p);				\
-	__smp_mb();							\
-	WRITE_ONCE(*p, v);						\
-} while (0)
-
-#define __smp_load_acquire(p)						\
-({									\
-	typeof(*p) ___p1 = READ_ONCE(*p);				\
-	compiletime_assert_atomic_type(*p);				\
-	__smp_mb();							\
-	___p1;								\
-})
-
-#else /* regular x86 TSO memory ordering */
-
 #define __smp_store_release(p, v)					\
 do {									\
 	compiletime_assert_atomic_type(*p);				\
@@ -79,8 +51,6 @@ do {									\
 	___p1;								\
 })
 
-#endif
-
 /* Atomic operations are already serializing on x86 */
 #define __smp_mb__before_atomic()	barrier()
 #define __smp_mb__after_atomic()	barrier()
arch/x86/include/asm/io.h +0 -15
index 95e948627fd0..f6e5b9375d8c 100644
@@ -232,21 +232,6 @@ extern void set_iounmap_nonlazy(void);
  */
 #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
 
-/*
- *	Cache management
- *
- *	This needed for two cases
- *	1. Out of order aware processors
- *	2. Accidentally out of order processors (PPro errata #51)
- */
-
-static inline void flush_write_buffers(void)
-{
-#if defined(CONFIG_X86_PPRO_FENCE)
-	asm volatile("lock; addl $0,0(%%esp)": : :"memory");
-#endif
-}
-
 #endif /* __KERNEL__ */
 
 extern void native_io_delay(void);
arch/x86/kernel/pci-nommu.c +0 -19
index b0caae27e1b7..c78df78b5ccd 100644
@@ -37,7 +37,6 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
 	WARN_ON(size == 0);
 	if (!check_addr("map_single", dev, bus, size))
 		return NOMMU_MAPPING_ERROR;
-	flush_write_buffers();
 	return bus;
 }
 
@@ -72,25 +71,9 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 			return 0;
 		s->dma_length = s->length;
 	}
-	flush_write_buffers();
 	return nents;
 }
 
-static void nommu_sync_single_for_device(struct device *dev,
-			dma_addr_t addr, size_t size,
-			enum dma_data_direction dir)
-{
-	flush_write_buffers();
-}
-
-
-static void nommu_sync_sg_for_device(struct device *dev,
-			struct scatterlist *sg, int nelems,
-			enum dma_data_direction dir)
-{
-	flush_write_buffers();
-}
-
 static int nommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
 	return dma_addr == NOMMU_MAPPING_ERROR;
@@ -101,8 +84,6 @@ const struct dma_map_ops nommu_dma_ops = {
 	.free			= dma_generic_free_coherent,
 	.map_sg			= nommu_map_sg,
 	.map_page		= nommu_map_page,
-	.sync_single_for_device = nommu_sync_single_for_device,
-	.sync_sg_for_device	= nommu_sync_sg_for_device,
 	.is_phys		= 1,
 	.mapping_error		= nommu_mapping_error,
 	.dma_supported		= x86_dma_supported,
arch/x86/um/asm/barrier.h +0 -4
index b7d73400ea29..f31e5d903161 100644
@@ -30,11 +30,7 @@
 
 #endif /* CONFIG_X86_32 */
 
-#ifdef CONFIG_X86_PPRO_FENCE
-#define dma_rmb()	rmb()
-#else /* CONFIG_X86_PPRO_FENCE */
 #define dma_rmb()	barrier()
-#endif /* CONFIG_X86_PPRO_FENCE */
 #define dma_wmb()	barrier()
 
 #include <asm-generic/barrier.h>
Signature · 1 line
2.14.2
#2 lore raw

PATCH 1/67 x86: remove X86_PPRO_FENCE

In reply to Christoph Hellwig

There were only a few Pentium Pro multiprocessors systems where this errata applied. They are more than 20 years old now, and we've slowly dropped places where put the workarounds in and discuraged anyone from enabling the workaround.

Get rid of it for good.

---
 arch/x86/Kconfig.cpu                        | 13 -------------
 arch/x86/entry/vdso/vdso32/vclock_gettime.c |  2 --
 arch/x86/include/asm/barrier.h              | 30 -----------------------------
 arch/x86/include/asm/io.h                   | 15 ---------------
 arch/x86/kernel/pci-nommu.c                 | 19 ------------------
 arch/x86/um/asm/barrier.h                   |  4 ----
 6 files changed, 83 deletions(-)
arch/x86/Kconfig.cpu +0 -13
index 65a9a4716e34..f0c5ef578153 100644
@@ -315,19 +315,6 @@ config X86_L1_CACHE_SHIFT
 	default "4" if MELAN || M486 || MGEODEGX1
 	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
 
-config X86_PPRO_FENCE
-	bool "PentiumPro memory ordering errata workaround"
-	depends on M686 || M586MMX || M586TSC || M586 || M486 || MGEODEGX1
-	---help---
-	  Old PentiumPro multiprocessor systems had errata that could cause
-	  memory operations to violate the x86 ordering standard in rare cases.
-	  Enabling this option will attempt to work around some (but not all)
-	  occurrences of this problem, at the cost of much heavier spinlock and
-	  memory barrier operations.
-
-	  If unsure, say n here. Even distro kernels should think twice before
-	  enabling this: there are few systems, and an unlikely bug.
-
 config X86_F00F_BUG
 	def_bool y
 	depends on M586MMX || M586TSC || M586 || M486
arch/x86/entry/vdso/vdso32/vclock_gettime.c +0 -2
index 7780bbfb06ef..9242b28418d5 100644
@@ -5,8 +5,6 @@
 #undef CONFIG_OPTIMIZE_INLINING
 #endif
 
-#undef CONFIG_X86_PPRO_FENCE
-
 #ifdef CONFIG_X86_64
 
 /*
arch/x86/include/asm/barrier.h +0 -30
index 7fb336210e1b..aa0f7449d4a4 100644
@@ -24,11 +24,7 @@
 #define wmb()	asm volatile("sfence" ::: "memory")
 #endif
 
-#ifdef CONFIG_X86_PPRO_FENCE
-#define dma_rmb()	rmb()
-#else
 #define dma_rmb()	barrier()
-#endif
 #define dma_wmb()	barrier()
 
 #ifdef CONFIG_X86_32
@@ -40,30 +36,6 @@
 #define __smp_wmb()	barrier()
 #define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
 
-#if defined(CONFIG_X86_PPRO_FENCE)
-
-/*
- * For this option x86 doesn't have a strong TSO memory
- * model and we should fall back to full barriers.
- */
-
-#define __smp_store_release(p, v)					\
-do {									\
-	compiletime_assert_atomic_type(*p);				\
-	__smp_mb();							\
-	WRITE_ONCE(*p, v);						\
-} while (0)
-
-#define __smp_load_acquire(p)						\
-({									\
-	typeof(*p) ___p1 = READ_ONCE(*p);				\
-	compiletime_assert_atomic_type(*p);				\
-	__smp_mb();							\
-	___p1;								\
-})
-
-#else /* regular x86 TSO memory ordering */
-
 #define __smp_store_release(p, v)					\
 do {									\
 	compiletime_assert_atomic_type(*p);				\
@@ -79,8 +51,6 @@ do {									\
 	___p1;								\
 })
 
-#endif
-
 /* Atomic operations are already serializing on x86 */
 #define __smp_mb__before_atomic()	barrier()
 #define __smp_mb__after_atomic()	barrier()
arch/x86/include/asm/io.h +0 -15
index 95e948627fd0..f6e5b9375d8c 100644
@@ -232,21 +232,6 @@ extern void set_iounmap_nonlazy(void);
  */
 #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
 
-/*
- *	Cache management
- *
- *	This needed for two cases
- *	1. Out of order aware processors
- *	2. Accidentally out of order processors (PPro errata #51)
- */
-
-static inline void flush_write_buffers(void)
-{
-#if defined(CONFIG_X86_PPRO_FENCE)
-	asm volatile("lock; addl $0,0(%%esp)": : :"memory");
-#endif
-}
-
 #endif /* __KERNEL__ */
 
 extern void native_io_delay(void);
arch/x86/kernel/pci-nommu.c +0 -19
index b0caae27e1b7..c78df78b5ccd 100644
@@ -37,7 +37,6 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
 	WARN_ON(size == 0);
 	if (!check_addr("map_single", dev, bus, size))
 		return NOMMU_MAPPING_ERROR;
-	flush_write_buffers();
 	return bus;
 }
 
@@ -72,25 +71,9 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 			return 0;
 		s->dma_length = s->length;
 	}
-	flush_write_buffers();
 	return nents;
 }
 
-static void nommu_sync_single_for_device(struct device *dev,
-			dma_addr_t addr, size_t size,
-			enum dma_data_direction dir)
-{
-	flush_write_buffers();
-}
-
-
-static void nommu_sync_sg_for_device(struct device *dev,
-			struct scatterlist *sg, int nelems,
-			enum dma_data_direction dir)
-{
-	flush_write_buffers();
-}
-
 static int nommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
 	return dma_addr == NOMMU_MAPPING_ERROR;
@@ -101,8 +84,6 @@ const struct dma_map_ops nommu_dma_ops = {
 	.free			= dma_generic_free_coherent,
 	.map_sg			= nommu_map_sg,
 	.map_page		= nommu_map_page,
-	.sync_single_for_device = nommu_sync_single_for_device,
-	.sync_sg_for_device	= nommu_sync_sg_for_device,
 	.is_phys		= 1,
 	.mapping_error		= nommu_mapping_error,
 	.dma_supported		= x86_dma_supported,
arch/x86/um/asm/barrier.h +0 -4
index b7d73400ea29..f31e5d903161 100644
@@ -30,11 +30,7 @@
 
 #endif /* CONFIG_X86_32 */
 
-#ifdef CONFIG_X86_PPRO_FENCE
-#define dma_rmb()	rmb()
-#else /* CONFIG_X86_PPRO_FENCE */
 #define dma_rmb()	barrier()
-#endif /* CONFIG_X86_PPRO_FENCE */
 #define dma_wmb()	barrier()
 
 #include <asm-generic/barrier.h>
Signature · 1 line
2.14.2
#3 lore raw

PATCH 2/67 alpha: mark jensen as broken

In reply to Christoph Hellwig

CONFIG_ALPHA_JENSEN has failed to compile since commit aca05038 ("alpha/dma: use common noop dma ops"), so mark it as broken.

---
 arch/alpha/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
index b31b974a03cb..e96adcbcab41 100644
@@ -209,6 +209,7 @@ config ALPHA_EIGER
 
 config ALPHA_JENSEN
 	bool "Jensen"
+	depends on BROKEN
 	help
 	  DEC PC 150 AXP (aka Jensen): This is a very old Digital system - one
 	  of the first-generation Alpha systems. A number of these systems
Signature · 1 line
2.14.2
#4 lore raw

Re: [PATCH 02/67] alpha: mark jensen as broken

Hi Christoph,

Quoted 2 lines · Christoph Hellwig

CONFIG_ALPHA_JENSEN has failed to compile since commit aca05038 ("alpha/dma: use common noop dma ops"), so mark it as broken.

unknown revision or path not in the working tree.
Ah, you dropped the leading "6":
6aca0503847f6329460b15b3ab2b0e30bb752793
is less than 2 years old, though.

Quoted 11 lines
---
 arch/alpha/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +0 -0
index b31b974a03cb..e96adcbcab41 100644

arch/alpha/Kconfig config ALPHA_EIGER · line 215

Quoted 7 lines
arch/alpha/Kconfig +1 -0
@@ -209,6 +209,7 @@ config ALPHA_EIGER
 
 config ALPHA_JENSEN
        bool "Jensen"
+       depends on BROKEN
        help
          DEC PC 150 AXP (aka Jensen): This is a very old Digital system - one
          of the first-generation Alpha systems. A number of these systems

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#5 lore raw

Re: [PATCH 02/67] alpha: mark jensen as broken

Quoted 10 lines · Geert Uytterhoeven

Hi Christoph,

Quoted 2 lines · Christoph Hellwig

CONFIG_ALPHA_JENSEN has failed to compile since commit aca05038 ("alpha/dma: use common noop dma ops"), so mark it as broken.

unknown revision or path not in the working tree.
Ah, you dropped the leading "6":
6aca0503847f6329460b15b3ab2b0e30bb752793
is less than 2 years old, though.

I'll fix the reference.

But 23 month of a whole sub-architecture not compiling should still be enough to mark it broken.

#6 lore raw

Re: [PATCH 02/67] alpha: mark jensen as broken

In reply to Geert Uytterhoeven
Quoted 10 lines · Geert Uytterhoeven

Hi Christoph,

Quoted 2 lines · Christoph Hellwig

CONFIG_ALPHA_JENSEN has failed to compile since commit aca05038 ("alpha/dma: use common noop dma ops"), so mark it as broken.

unknown revision or path not in the working tree.
Ah, you dropped the leading "6":
6aca0503847f6329460b15b3ab2b0e30bb752793
is less than 2 years old, though.

I'll fix the reference.

But 23 month of a whole sub-architecture not compiling should still be enough to mark it broken.

#7 lore raw

PATCH 2/67 alpha: mark jensen as broken

In reply to Christoph Hellwig

CONFIG_ALPHA_JENSEN has failed to compile since commit aca05038 ("alpha/dma: use common noop dma ops"), so mark it as broken.

---
 arch/alpha/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
index b31b974a03cb..e96adcbcab41 100644
@@ -209,6 +209,7 @@ config ALPHA_EIGER
 
 config ALPHA_JENSEN
 	bool "Jensen"
+	depends on BROKEN
 	help
 	  DEC PC 150 AXP (aka Jensen): This is a very old Digital system - one
 	  of the first-generation Alpha systems. A number of these systems
Signature · 1 line
2.14.2
#8 lore raw

PATCH 3/67 dma-mapping: take dma_pfn_offset into account in dma_max_pfn

In reply to Christoph Hellwig

This makes sure the generic version can be used with architectures / devices that have a DMA offset in the direct mapping.

---
 include/linux/dma-mapping.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/dma-mapping.h +1 -1
index 81ed9b2d84dc..d84951865be7 100644
@@ -692,7 +692,7 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)
 #ifndef dma_max_pfn
 static inline unsigned long dma_max_pfn(struct device *dev)
 {
-	return *dev->dma_mask >> PAGE_SHIFT;
+	return (*dev->dma_mask >> PAGE_SHIFT) + dev->dma_pfn_offset;
 }
 #endif
 
Signature · 1 line
2.14.2
#9 lore raw

PATCH 3/67 dma-mapping: take dma_pfn_offset into account in dma_max_pfn

In reply to Christoph Hellwig

This makes sure the generic version can be used with architectures / devices that have a DMA offset in the direct mapping.

---
 include/linux/dma-mapping.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/dma-mapping.h +1 -1
index 81ed9b2d84dc..d84951865be7 100644
@@ -692,7 +692,7 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)
 #ifndef dma_max_pfn
 static inline unsigned long dma_max_pfn(struct device *dev)
 {
-	return *dev->dma_mask >> PAGE_SHIFT;
+	return (*dev->dma_mask >> PAGE_SHIFT) + dev->dma_pfn_offset;
 }
 #endif
 
Signature · 1 line
2.14.2
#10 lore raw

PATCH 4/67 arm64: don't override dma_max_pfn

In reply to Christoph Hellwig

The generic version now takes dma_pfn_offset into account, so there is no more need for an architecture override.

---
 arch/arm64/include/asm/dma-mapping.h | 9 ---------
 1 file changed, 9 deletions(-)
arch/arm64/include/asm/dma-mapping.h +0 -9
index 0df756b24863..eada887a93bf 100644
@@ -76,14 +76,5 @@ static inline void dma_mark_clean(void *addr, size_t size)
 {
 }
 
-/* Override for dma_max_pfn() */
-static inline unsigned long dma_max_pfn(struct device *dev)
-{
-	dma_addr_t dma_max = (dma_addr_t)*dev->dma_mask;
-
-	return (ulong)dma_to_phys(dev, dma_max) >> PAGE_SHIFT;
-}
-#define dma_max_pfn(dev) dma_max_pfn(dev)
-
 #endif	/* __KERNEL__ */
 #endif	/* __ASM_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#11 lore raw

PATCH 4/67 arm64: don't override dma_max_pfn

In reply to Christoph Hellwig

The generic version now takes dma_pfn_offset into account, so there is no more need for an architecture override.

---
 arch/arm64/include/asm/dma-mapping.h | 9 ---------
 1 file changed, 9 deletions(-)
arch/arm64/include/asm/dma-mapping.h +0 -9
index 0df756b24863..eada887a93bf 100644
@@ -76,14 +76,5 @@ static inline void dma_mark_clean(void *addr, size_t size)
 {
 }
 
-/* Override for dma_max_pfn() */
-static inline unsigned long dma_max_pfn(struct device *dev)
-{
-	dma_addr_t dma_max = (dma_addr_t)*dev->dma_mask;
-
-	return (ulong)dma_to_phys(dev, dma_max) >> PAGE_SHIFT;
-}
-#define dma_max_pfn(dev) dma_max_pfn(dev)
-
 #endif	/* __KERNEL__ */
 #endif	/* __ASM_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#12 lore raw

PATCH 5/67 dma-mapping: replace PCI_DMA_BUS_IS_PHYS with a flag in struct dma_map_ops

In reply to Christoph Hellwig

The current PCI_DMA_BUS_IS_PHYS decided if a dma implementation is bound by the dma mask in the device because it directly maps to a physical address range (modulo an offset in the device), or if it is virtualized by an iommu and can map any address (that includes virtual iommus like swiotlb). The problem with this scheme is that it is per-architecture and not per dma_ops instance, and we are growing more and more setups that have multiple different dma operations in use on a single system, for which this scheme can't provide a correct answer. Depending on the architecture that means we either get a false positive or false negative at the moment.

This patch instead extents the is_phys flag in struct dma_map_ops that is currently only used by a few architectures to be used tree wide.

Note that this means that we now need a struct device parent in the Scsi_Host or netdevice. Every modern driver has these, but there might still be a few outdated legacy drivers out there, which now won't make an intelligent decision.

---
 arch/alpha/include/asm/pci.h          |  5 -----
 arch/alpha/kernel/pci-noop.c          |  1 +
 arch/arc/include/asm/pci.h            |  6 ------
 arch/arc/mm/dma.c                     |  1 +
 arch/arm/include/asm/pci.h            |  7 -------
 arch/arm/mm/dma-mapping-nommu.c       |  1 +
 arch/arm/mm/dma-mapping.c             |  2 ++
 arch/arm64/include/asm/pci.h          |  5 -----
 arch/blackfin/kernel/dma-mapping.c    |  2 ++
 arch/c6x/kernel/dma.c                 |  1 +
 arch/cris/arch-v32/drivers/pci/dma.c  |  1 +
 arch/cris/include/asm/pci.h           |  6 ------
 arch/frv/mb93090-mb00/pci-dma-nommu.c |  1 +
 arch/frv/mb93090-mb00/pci-dma.c       |  1 +
 arch/h8300/include/asm/pci.h          |  2 --
 arch/h8300/kernel/dma.c               |  1 +
 arch/hexagon/kernel/dma.c             |  2 +-
 arch/ia64/hp/common/sba_iommu.c       |  3 ---
 arch/ia64/include/asm/pci.h           | 17 -----------------
 arch/ia64/kernel/setup.c              | 12 ------------
 arch/ia64/sn/kernel/io_common.c       |  5 -----
 arch/m68k/include/asm/pci.h           |  6 ------
 arch/m68k/kernel/dma.c                |  1 +
 arch/metag/kernel/dma.c               |  1 +
 arch/microblaze/include/asm/pci.h     |  6 ------
 arch/microblaze/kernel/dma.c          |  1 +
 arch/mips/include/asm/pci.h           |  7 -------
 arch/mips/mm/dma-default.c            |  1 +
 arch/mn10300/include/asm/pci.h        |  6 ------
 arch/mn10300/mm/dma-alloc.c           |  1 +
 arch/nios2/mm/dma-mapping.c           |  1 +
 arch/openrisc/kernel/dma.c            |  1 +
 arch/parisc/include/asm/pci.h         | 23 -----------------------
 arch/parisc/kernel/pci-dma.c          |  2 ++
 arch/parisc/kernel/setup.c            |  5 -----
 arch/powerpc/include/asm/pci.h        | 18 ------------------
 arch/powerpc/kernel/dma.c             |  1 +
 arch/riscv/include/asm/pci.h          |  3 ---
 arch/s390/include/asm/pci.h           |  2 --
 arch/s390/pci/pci_dma.c               |  3 ---
 arch/sh/include/asm/pci.h             |  6 ------
 arch/sh/kernel/dma-nommu.c            |  2 +-
 arch/sparc/include/asm/pci_32.h       |  4 ----
 arch/sparc/include/asm/pci_64.h       |  6 ------
 arch/sparc/kernel/ioport.c            |  1 +
 arch/tile/include/asm/pci.h           | 14 --------------
 arch/tile/kernel/pci-dma.c            |  2 ++
 arch/x86/include/asm/pci.h            |  2 --
 arch/x86/kernel/pci-nommu.c           |  2 +-
 arch/xtensa/include/asm/pci.h         |  7 -------
 arch/xtensa/kernel/pci-dma.c          |  1 +
 drivers/ide/ide-lib.c                 |  5 ++---
 drivers/ide/ide-probe.c               |  2 +-
 drivers/parisc/ccio-dma.c             |  2 --
 drivers/parisc/sba_iommu.c            |  2 --
 drivers/pci/host/vmd.c                |  1 +
 drivers/scsi/scsi_lib.c               | 14 ++++++--------
 include/asm-generic/pci.h             |  8 --------
 include/linux/dma-mapping.h           | 23 ++++++++++++++++++++++-
 lib/dma-noop.c                        |  1 +
 net/core/dev.c                        | 18 ++++++++----------
 tools/virtio/linux/dma-mapping.h      |  2 --
 62 files changed, 70 insertions(+), 226 deletions(-)
arch/alpha/include/asm/pci.h +0 -5
index b9ec55351924..cf6bc1e64d66 100644
@@ -56,11 +56,6 @@ struct pci_controller {
 
 /* IOMMU controls.  */
 
-/* The PCI address space does not equal the physical memory address space.
-   The networking and block device layers use this boolean for bounce buffer
-   decisions.  */
-#define PCI_DMA_BUS_IS_PHYS  0
-
 /* TODO: integrate with include/asm-generic/pci.h ? */
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
arch/alpha/kernel/pci-noop.c +1 -0
index b995987b1557..d3208254b269 100644
@@ -132,6 +132,7 @@ const struct dma_map_ops alpha_noop_ops = {
 	.map_sg			= dma_noop_map_sg,
 	.mapping_error		= dma_noop_mapping_error,
 	.dma_supported		= alpha_noop_supported,
+	.is_phys		= true,
 };
 
 const struct dma_map_ops *dma_ops = &alpha_noop_ops;
arch/arc/include/asm/pci.h +0 -6
index ba56c23c1b20..4ff53c041c64 100644
@@ -16,12 +16,6 @@
 #define PCIBIOS_MIN_MEM 0x100000
 
 #define pcibios_assign_all_busses()	1
-/*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	1
 
 #endif /* __KERNEL__ */
 
arch/arc/mm/dma.c +1 -0
index e9d93604ad0f..fad18261ef6a 100644
@@ -274,5 +274,6 @@ const struct dma_map_ops arc_dma_ops = {
 	.sync_sg_for_cpu	= arc_dma_sync_sg_for_cpu,
 	.sync_sg_for_device	= arc_dma_sync_sg_for_device,
 	.dma_supported		= arc_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(arc_dma_ops);
arch/arm/include/asm/pci.h +0 -7
index 960d9dc4f380..05b2eb2dc76f 100644
@@ -22,13 +22,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif /* CONFIG_PCI_DOMAINS */
 
-/*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
 #define HAVE_PCI_MMAP
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE
 
arch/arm/mm/dma-mapping-nommu.c +1 -0
index 6db5fc26d154..1cced700e45a 100644
@@ -208,6 +208,7 @@ const struct dma_map_ops arm_nommu_dma_ops = {
 	.sync_single_for_cpu	= arm_nommu_dma_sync_single_for_cpu,
 	.sync_sg_for_device	= arm_nommu_dma_sync_sg_for_device,
 	.sync_sg_for_cpu	= arm_nommu_dma_sync_sg_for_cpu,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(arm_nommu_dma_ops);
 
arch/arm/mm/dma-mapping.c +2 -0
index ada8eb206a90..8e120e2d9cac 100644
@@ -200,6 +200,7 @@ const struct dma_map_ops arm_dma_ops = {
 	.sync_sg_for_device	= arm_dma_sync_sg_for_device,
 	.mapping_error		= arm_dma_mapping_error,
 	.dma_supported		= arm_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(arm_dma_ops);
 
@@ -220,6 +221,7 @@ const struct dma_map_ops arm_coherent_dma_ops = {
 	.map_sg			= arm_dma_map_sg,
 	.mapping_error		= arm_dma_mapping_error,
 	.dma_supported		= arm_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(arm_coherent_dma_ops);
 
arch/arm64/include/asm/pci.h +0 -5
index 8747f7c5e0e7..9e690686e8aa 100644
@@ -18,11 +18,6 @@
 #define pcibios_assign_all_busses() \
 	(pci_has_flag(PCI_REASSIGN_ALL_BUS))
 
-/*
- * PCI address space differs from physical memory address space
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE	1
 
 extern int isa_dma_bridge_buggy;
arch/blackfin/kernel/dma-mapping.c +2 -0
index 477bb29a7987..362902a2a418 100644
@@ -168,5 +168,7 @@ const struct dma_map_ops bfin_dma_ops = {
 
 	.sync_single_for_device	= bfin_dma_sync_single_for_device,
 	.sync_sg_for_device	= bfin_dma_sync_sg_for_device,
+
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(bfin_dma_ops);
arch/c6x/kernel/dma.c +1 -0
index 9fff8be75f58..a526dddeeac1 100644
@@ -134,6 +134,7 @@ const struct dma_map_ops c6x_dma_ops = {
 	.sync_single_for_cpu	= c6x_dma_sync_single_for_cpu,
 	.sync_sg_for_device	= c6x_dma_sync_sg_for_device,
 	.sync_sg_for_cpu	= c6x_dma_sync_sg_for_cpu,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(c6x_dma_ops);
 
arch/cris/arch-v32/drivers/pci/dma.c +1 -0
index dbbd3816cc0b..aa16ce27e036 100644
@@ -76,5 +76,6 @@ const struct dma_map_ops v32_dma_ops = {
 	.map_page		= v32_dma_map_page,
 	.map_sg                 = v32_dma_map_sg,
 	.dma_supported		= v32_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(v32_dma_ops);
arch/cris/include/asm/pci.h +0 -6
index dcfef6407ae6..eb1f7f172f4b 100644
@@ -27,12 +27,6 @@
 #include <linux/string.h>
 #include <asm/io.h>
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 #define HAVE_PCI_MMAP
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE
 
arch/frv/mb93090-mb00/pci-dma-nommu.c +1 -0
index 4a96de7f0af4..d58d701619e5 100644
@@ -172,5 +172,6 @@ const struct dma_map_ops frv_dma_ops = {
 	.sync_single_for_device	= frv_dma_sync_single_for_device,
 	.sync_sg_for_device	= frv_dma_sync_sg_for_device,
 	.dma_supported		= frv_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(frv_dma_ops);
arch/frv/mb93090-mb00/pci-dma.c +1 -0
index e7130abc0dae..8c2e9a40e57e 100644
@@ -114,5 +114,6 @@ const struct dma_map_ops frv_dma_ops = {
 	.sync_single_for_device	= frv_dma_sync_single_for_device,
 	.sync_sg_for_device	= frv_dma_sync_sg_for_device,
 	.dma_supported		= frv_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(frv_dma_ops);
arch/h8300/include/asm/pci.h +0 -2
index 7c9e55d62215..d4d345a52092 100644
@@ -15,6 +15,4 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
 	/* We don't do dynamic PCI IRQ allocation */
 }
 
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 #endif /* _ASM_H8300_PCI_H */
arch/h8300/kernel/dma.c +1 -0
index 225dd0a188dc..0e92214310c4 100644
@@ -65,5 +65,6 @@ const struct dma_map_ops h8300_dma_map_ops = {
 	.free = dma_free,
 	.map_page = map_page,
 	.map_sg = map_sg,
+	.is_phys = true,
 };
 EXPORT_SYMBOL(h8300_dma_map_ops);
arch/hexagon/kernel/dma.c +1 -1
index 546792d176a4..3683bb9c05a2 100644
@@ -207,7 +207,7 @@ const struct dma_map_ops hexagon_dma_ops = {
 	.sync_single_for_cpu = hexagon_sync_single_for_cpu,
 	.sync_single_for_device = hexagon_sync_single_for_device,
 	.mapping_error	= hexagon_mapping_error,
-	.is_phys	= 1,
+	.is_phys	= true,
 };
 
 void __init hexagon_dma_init(void)
arch/ia64/hp/common/sba_iommu.c +0 -3
index aec4a3354abe..6f05aba9012f 100644
@@ -1845,9 +1845,6 @@ static void ioc_init(unsigned long hpa, struct ioc *ioc)
 	ioc_resource_init(ioc);
 	ioc_sac_init(ioc);
 
-	if ((long) ~iovp_mask > (long) ia64_max_iommu_merge_mask)
-		ia64_max_iommu_merge_mask = ~iovp_mask;
-
 	printk(KERN_INFO PFX
 		"%s %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
 		ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
arch/ia64/include/asm/pci.h +0 -17
index b1d04e8bafc8..780e8744ba85 100644
@@ -30,23 +30,6 @@ struct pci_vector_struct {
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
 
-/*
- * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct
- * correspondence between device bus addresses and CPU physical addresses.
- * Platforms with a hardware I/O MMU _must_ turn this off to suppress the
- * bounce buffer handling code in the block and network device layers.
- * Platforms with separate bus address spaces _must_ turn this off and provide
- * a device DMA mapping implementation that takes care of the necessary
- * address translation.
- *
- * For now, the ia64 platforms which may have separate/multiple bus address
- * spaces all have I/O MMUs which support the merging of physically
- * discontiguous buffers, so we can use that as the sole factor to determine
- * the setting of PCI_DMA_BUS_IS_PHYS.
- */
-extern unsigned long ia64_max_iommu_merge_mask;
-#define PCI_DMA_BUS_IS_PHYS	(ia64_max_iommu_merge_mask == ~0UL)
-
 #define HAVE_PCI_MMAP
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE
 #define arch_can_pci_mmap_wc()	1
arch/ia64/kernel/setup.c +0 -12
index dee56bcb993d..ad43cbf70628 100644
@@ -123,18 +123,6 @@ unsigned long ia64_i_cache_stride_shift = ~0;
 #define	CACHE_STRIDE_SHIFT	5
 unsigned long ia64_cache_stride_shift = ~0;
 
-/*
- * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
- * mask specifies a mask of address bits that must be 0 in order for two buffers to be
- * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start
- * address of the second buffer must be aligned to (merge_mask+1) in order to be
- * mergeable).  By default, we assume there is no I/O MMU which can merge physically
- * discontiguous buffers, so we set the merge_mask to ~0UL, which corresponds to a iommu
- * page-size of 2^64.
- */
-unsigned long ia64_max_iommu_merge_mask = ~0UL;
-EXPORT_SYMBOL(ia64_max_iommu_merge_mask);
-
 /*
  * We use a special marker for the end of memory and it uses the extra (+1) slot
  */
arch/ia64/sn/kernel/io_common.c +0 -5
index 11f2275570fb..8479e9a7ce16 100644
@@ -480,11 +480,6 @@ sn_io_early_init(void)
 	tioca_init_provider();
 	tioce_init_provider();
 
-	/*
-	 * This is needed to avoid bounce limit checks in the blk layer
-	 */
-	ia64_max_iommu_merge_mask = ~PAGE_MASK;
-
 	sn_irq_lh_init();
 	INIT_LIST_HEAD(&sn_sysdata_list);
 	sn_init_cpei_timer();
arch/m68k/include/asm/pci.h +0 -6
index ef26fae8cf0b..5a4bc223743b 100644
@@ -4,12 +4,6 @@
 
 #include <asm-generic/pci.h>
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 #define	pcibios_assign_all_busses()	1
 
 #define	PCIBIOS_MIN_IO		0x00000100
arch/m68k/kernel/dma.c +1 -0
index 87ef73a93856..e0167418072b 100644
@@ -165,5 +165,6 @@ const struct dma_map_ops m68k_dma_ops = {
 	.map_sg			= m68k_dma_map_sg,
 	.sync_single_for_device	= m68k_dma_sync_single_for_device,
 	.sync_sg_for_device	= m68k_dma_sync_sg_for_device,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(m68k_dma_ops);
arch/metag/kernel/dma.c +1 -0
index f0ab3a498328..16cb4df51b8a 100644
@@ -584,5 +584,6 @@ const struct dma_map_ops metag_dma_ops = {
 	.sync_single_for_cpu	= metag_dma_sync_single_for_cpu,
 	.sync_sg_for_cpu	= metag_dma_sync_sg_for_cpu,
 	.mmap			= metag_dma_mmap,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(metag_dma_ops);
arch/microblaze/include/asm/pci.h +0 -6
index 114b93488193..00478965f932 100644
@@ -61,12 +61,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 
 #define HAVE_PCI_LEGACY	1
 
-/* The PCI address space does equal the physical memory
- * address space (no IOMMU).  The IDE and SCSI device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
 extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
arch/microblaze/kernel/dma.c +1 -0
index 990bf9ea0ec6..2a9a0ec14c46 100644
@@ -216,6 +216,7 @@ const struct dma_map_ops dma_direct_ops = {
 	.sync_single_for_device		= dma_direct_sync_single_for_device,
 	.sync_sg_for_cpu		= dma_direct_sync_sg_for_cpu,
 	.sync_sg_for_device		= dma_direct_sync_sg_for_device,
+	.is_phys	= true,
 };
 EXPORT_SYMBOL(dma_direct_ops);
 
arch/mips/include/asm/pci.h +0 -7
index 2339f42f047a..436099883022 100644
@@ -121,13 +121,6 @@ extern unsigned long PCIBIOS_MIN_MEM;
 #include <linux/string.h>
 #include <asm/io.h>
 
-/*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
 #ifdef CONFIG_PCI_DOMAINS_GENERIC
 static inline int pci_proc_domain(struct pci_bus *bus)
 {
arch/mips/mm/dma-default.c +1 -0
index e3e94d05f0fd..3cd93e0c7a29 100644
@@ -407,6 +407,7 @@ static const struct dma_map_ops mips_default_dma_map_ops = {
 	.mapping_error = mips_dma_mapping_error,
 	.dma_supported = mips_dma_supported,
 	.cache_sync = mips_dma_cache_sync,
+	.is_phys = true,
 };
 
 const struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
arch/mn10300/include/asm/pci.h +0 -6
index 5b75a1b2c4f6..6132966bdf30 100644
@@ -57,12 +57,6 @@ extern void unit_pci_init(void);
 #include <linux/string.h>
 #include <asm/io.h>
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 /* Return the index of the PCI controller for device. */
 static inline int pci_controller_num(struct pci_dev *dev)
 {
arch/mn10300/mm/dma-alloc.c +1 -0
index 86108d2496b3..55876a87c247 100644
@@ -128,4 +128,5 @@ const struct dma_map_ops mn10300_dma_ops = {
 	.map_sg			= mn10300_dma_map_sg,
 	.sync_single_for_device	= mn10300_dma_sync_single_for_device,
 	.sync_sg_for_device	= mn10300_dma_sync_sg_for_device,
+	.is_phys		= true,
 };
arch/nios2/mm/dma-mapping.c +1 -0
index 7040c1adbb5e..599bcc09c9e7 100644
@@ -203,5 +203,6 @@ const struct dma_map_ops nios2_dma_ops = {
 	.sync_single_for_cpu	= nios2_dma_sync_single_for_cpu,
 	.sync_sg_for_cpu	= nios2_dma_sync_sg_for_cpu,
 	.sync_sg_for_device	= nios2_dma_sync_sg_for_device,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(nios2_dma_ops);
arch/openrisc/kernel/dma.c +1 -0
index a945f00011b4..7faad429d3dc 100644
@@ -245,6 +245,7 @@ const struct dma_map_ops or1k_dma_map_ops = {
 	.unmap_sg = or1k_unmap_sg,
 	.sync_single_for_cpu = or1k_sync_single_for_cpu,
 	.sync_single_for_device = or1k_sync_single_for_device,
+	.is_phys = true,
 };
 EXPORT_SYMBOL(or1k_dma_map_ops);
 
arch/parisc/include/asm/pci.h +0 -23
index 96b7deec512d..3328fd17c19d 100644
@@ -87,29 +87,6 @@ struct pci_hba_data {
 #define PCI_F_EXTEND		0UL
 #endif /* !CONFIG_64BIT */
 
-/*
- * If the PCI device's view of memory is the same as the CPU's view of memory,
- * PCI_DMA_BUS_IS_PHYS is true.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#ifdef CONFIG_PA20
-/* All PA-2.0 machines have an IOMMU. */
-#define PCI_DMA_BUS_IS_PHYS	0
-#define parisc_has_iommu()	do { } while (0)
-#else
-
-#if defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA)
-extern int parisc_bus_is_phys; 	/* in arch/parisc/kernel/setup.c */
-#define PCI_DMA_BUS_IS_PHYS	parisc_bus_is_phys
-#define parisc_has_iommu()	do { parisc_bus_is_phys = 0; } while (0)
-#else
-#define PCI_DMA_BUS_IS_PHYS	1
-#define parisc_has_iommu()	do { } while (0)
-#endif
-
-#endif	/* !CONFIG_PA20 */
-
-
 /*
 ** Most PCI devices (eg Tulip, NCR720) also export the same registers
 ** to both MMIO and I/O port space.  Due to poor performance of I/O Port
arch/parisc/kernel/pci-dma.c +2 -0
index c0dfd892f70c..6ad9aed3d025 100644
@@ -591,6 +591,7 @@ const struct dma_map_ops pcxl_dma_ops = {
 	.sync_sg_for_cpu =	pa11_dma_sync_sg_for_cpu,
 	.sync_sg_for_device =	pa11_dma_sync_sg_for_device,
 	.cache_sync =		pa11_dma_cache_sync,
+	.is_phys =		true,
 };
 
 static void *pcx_dma_alloc(struct device *dev, size_t size,
@@ -628,4 +629,5 @@ const struct dma_map_ops pcx_dma_ops = {
 	.sync_sg_for_cpu =	pa11_dma_sync_sg_for_cpu,
 	.sync_sg_for_device =	pa11_dma_sync_sg_for_device,
 	.cache_sync =		pa11_dma_cache_sync,
+	.is_phys =		true,
 };
arch/parisc/kernel/setup.c +0 -5
index 0e9675f857a5..8d3a7b80ac42 100644
@@ -58,11 +58,6 @@ struct proc_dir_entry * proc_runway_root __read_mostly = NULL;
 struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
 struct proc_dir_entry * proc_mckinley_root __read_mostly = NULL;
 
-#if !defined(CONFIG_PA20) && (defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA))
-int parisc_bus_is_phys __read_mostly = 1;	/* Assume no IOMMU is present */
-EXPORT_SYMBOL(parisc_bus_is_phys);
-#endif
-
 void __init setup_cmdline(char **cmdline_p)
 {
 	extern unsigned int boot_args[];
arch/powerpc/include/asm/pci.h +0 -18
index 8dc32eacc97c..04c1347e2c51 100644
@@ -91,24 +91,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 
 #define HAVE_PCI_LEGACY	1
 
-#ifdef CONFIG_PPC64
-
-/* The PCI address space does not equal the physical memory address
- * space (we have an IOMMU).  The IDE and SCSI device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
-#else /* 32-bit */
-
-/* The PCI address space does equal the physical memory
- * address space (no IOMMU).  The IDE and SCSI device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
-#endif /* CONFIG_PPC64 */
-
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
 extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
arch/powerpc/kernel/dma.c +1 -0
index 4194bbbbdb10..df0e7bb97ab5 100644
@@ -290,6 +290,7 @@ const struct dma_map_ops dma_direct_ops = {
 	.sync_sg_for_cpu 		= dma_direct_sync_sg,
 	.sync_sg_for_device 		= dma_direct_sync_sg,
 #endif
+	.is_phys			= true,
 };
 EXPORT_SYMBOL(dma_direct_ops);
 
arch/riscv/include/asm/pci.h +0 -3
index 0f2fc9ef20fc..b3638c505728 100644
@@ -26,9 +26,6 @@
 /* RISC-V shim does not initialize PCI bus */
 #define pcibios_assign_all_busses() 1
 
-/* We do not have an IOMMU */
-#define PCI_DMA_BUS_IS_PHYS 1
-
 extern int isa_dma_bridge_buggy;
 
 #ifdef CONFIG_PCI
arch/s390/include/asm/pci.h +0 -2
index 12fe3591034f..94f8db468c9b 100644
@@ -2,8 +2,6 @@
 #ifndef __ASM_S390_PCI_H
 #define __ASM_S390_PCI_H
 
-/* must be set before including asm-generic/pci.h */
-#define PCI_DMA_BUS_IS_PHYS (0)
 /* must be set before including pci_clp.h */
 #define PCI_BAR_COUNT	6
 
arch/s390/pci/pci_dma.c +0 -3
index f7aa5a77827e..90826e2010da 100644
@@ -668,9 +668,6 @@ const struct dma_map_ops s390_pci_dma_ops = {
 	.map_page	= s390_dma_map_pages,
 	.unmap_page	= s390_dma_unmap_pages,
 	.mapping_error	= s390_mapping_error,
-	/* if we support direct DMA this must be conditional */
-	.is_phys	= 0,
-	/* dma_supported is unconditionally true without a callback */
 };
 EXPORT_SYMBOL_GPL(s390_pci_dma_ops);
 
arch/sh/include/asm/pci.h +0 -6
index 0033f0df2b3b..10a36b1cf2ea 100644
@@ -71,12 +71,6 @@ extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM;
  * SuperH has everything mapped statically like x86.
  */
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(dma_ops->is_phys)
-
 #ifdef CONFIG_PCI
 /*
  * None of the SH PCI controllers support MWI, it is always treated as a
arch/sh/kernel/dma-nommu.c +1 -1
index 62b485107eae..a2ef7f19610d 100644
@@ -75,7 +75,7 @@ const struct dma_map_ops nommu_dma_ops = {
 	.sync_single_for_device	= nommu_sync_single_for_device,
 	.sync_sg_for_device	= nommu_sync_sg_for_device,
 #endif
-	.is_phys		= 1,
+	.is_phys		= true,
 };
 
 void __init no_iommu_init(void)
arch/sparc/include/asm/pci_32.h +0 -4
index 98917e48727d..cfc0ee9476c6 100644
@@ -17,10 +17,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-/* Dynamic DMA mapping stuff.
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
 #endif /* __KERNEL__ */
 
 #ifndef CONFIG_LEON_PCI
arch/sparc/include/asm/pci_64.h +0 -6
index 671274e36cfa..fac77813402c 100644
@@ -17,12 +17,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-/* The PCI address space does not equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
 /* PCI IOMMU mapping bypass support. */
 
 /* PCI 64-bit addressing works for all slots on all controller
arch/sparc/kernel/ioport.c +1 -0
index 7eeef80c02f7..a401e8e0579d 100644
@@ -656,6 +656,7 @@ const struct dma_map_ops pci32_dma_ops = {
 	.sync_single_for_device	= pci32_sync_single_for_device,
 	.sync_sg_for_cpu	= pci32_sync_sg_for_cpu,
 	.sync_sg_for_device	= pci32_sync_sg_for_device,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(pci32_dma_ops);
 
arch/tile/include/asm/pci.h +0 -14
index fe3de505b024..8b910e3f0620 100644
@@ -52,13 +52,6 @@ static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
 
 #define	TILE_NUM_PCIE	2
 
-/*
- * The hypervisor maps the entirety of CPA-space as bus addresses, so
- * bus addresses are physical addresses.  The networking and block
- * device layers use this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     1
-
 /* generic pci stuff */
 #include <asm-generic/pci.h>
 
@@ -185,13 +178,6 @@ extern int num_trio_shims;
 
 extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
 
-/*
- * The PCI address space does not equal the physical memory address
- * space (we have an IOMMU). The IDE and SCSI device layers use this
- * boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     0
-
 #endif /* __tilegx__ */
 
 int __init tile_pci_init(void);
arch/tile/kernel/pci-dma.c +2 -0
index f2abedc8a080..9072e2c25e59 100644
@@ -328,6 +328,7 @@ static const struct dma_map_ops tile_default_dma_map_ops = {
 	.sync_single_for_device = tile_dma_sync_single_for_device,
 	.sync_sg_for_cpu = tile_dma_sync_sg_for_cpu,
 	.sync_sg_for_device = tile_dma_sync_sg_for_device,
+	.is_phys = true,
 };
 
 const struct dma_map_ops *tile_dma_map_ops = &tile_default_dma_map_ops;
@@ -501,6 +502,7 @@ static const struct dma_map_ops tile_pci_default_dma_map_ops = {
 	.sync_single_for_device = tile_pci_dma_sync_single_for_device,
 	.sync_sg_for_cpu = tile_pci_dma_sync_sg_for_cpu,
 	.sync_sg_for_device = tile_pci_dma_sync_sg_for_device,
+	.is_phys = true,
 };
 
 const struct dma_map_ops *gx_pci_dma_map_ops = &tile_pci_default_dma_map_ops;
arch/x86/include/asm/pci.h +0 -2
index d32175e30259..fecde74ff549 100644
@@ -118,8 +118,6 @@ void native_restore_msi_irqs(struct pci_dev *dev);
 #define native_teardown_msi_irq		NULL
 #endif
 
-#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-
 #endif  /* __KERNEL__ */
 
 #ifdef CONFIG_X86_64
arch/x86/kernel/pci-nommu.c +1 -1
index c78df78b5ccd..8ac9d1fe0373 100644
@@ -84,7 +84,7 @@ const struct dma_map_ops nommu_dma_ops = {
 	.free			= dma_generic_free_coherent,
 	.map_sg			= nommu_map_sg,
 	.map_page		= nommu_map_page,
-	.is_phys		= 1,
 	.mapping_error		= nommu_mapping_error,
 	.dma_supported		= x86_dma_supported,
+	.is_phys		= true,
 };
arch/xtensa/include/asm/pci.h +0 -7
index 5c83798e3b2e..7949349294c7 100644
@@ -37,13 +37,6 @@ extern struct pci_controller* pcibios_alloc_controller(void);
 #include <linux/string.h>
 #include <asm/io.h>
 
-/* The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce buffer
- * decisions.
- */
-
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
 #define HAVE_PCI_MMAP		1
 #define arch_can_pci_mmap_io()	1
arch/xtensa/kernel/pci-dma.c +1 -0
index 623720a11143..4a51996d2919 100644
@@ -239,6 +239,7 @@ const struct dma_map_ops xtensa_dma_map_ops = {
 	.sync_sg_for_cpu = xtensa_sync_sg_for_cpu,
 	.sync_sg_for_device = xtensa_sync_sg_for_device,
 	.mapping_error = xtensa_dma_mapping_error,
+	.is_phys = true,
 };
 EXPORT_SYMBOL(xtensa_dma_map_ops);
 
drivers/ide/ide-lib.c +2 -3
index e1180fa46196..0cdd661ddee0 100644
@@ -17,13 +17,12 @@
 
 void ide_toggle_bounce(ide_drive_t *drive, int on)
 {
+	struct device *dev = drive->hwif ? drive->hwif->dev : NULL;
 	u64 addr = BLK_BOUNCE_HIGH;	/* dma64_addr_t */
 
-	if (!PCI_DMA_BUS_IS_PHYS) {
+	if (dev && !dma_is_phys(dev)) {
 		addr = BLK_BOUNCE_ANY;
 	} else if (on && drive->media == ide_disk) {
-		struct device *dev = drive->hwif->dev;
-
 		if (dev && dev->dma_mask)
 			addr = *dev->dma_mask;
 	}
drivers/ide/ide-probe.c +1 -1
index 17fd55af4d92..7fe4d751e6cf 100644
@@ -796,7 +796,7 @@ static int ide_init_queue(ide_drive_t *drive)
 	 * This will be fixed once we teach pci_map_sg() about our boundary
 	 * requirements, hopefully soon. *FIXME*
 	 */
-	if (!PCI_DMA_BUS_IS_PHYS)
+	if (hwif->dev && !dma_is_phys(hwif->dev))
 		max_sg_entries >>= 1;
 #endif /* CONFIG_PCI */
 
drivers/parisc/ccio-dma.c +0 -2
index acba1f56af3e..2b129d8525d5 100644
@@ -1596,8 +1596,6 @@ static int __init ccio_probe(struct parisc_device *dev)
 	}
 #endif
 	ioc_count++;
-
-	parisc_has_iommu();
 	return 0;
 }
 
drivers/parisc/sba_iommu.c +0 -2
index 0a9c762a70fa..a58c586ebd81 100644
@@ -2017,8 +2017,6 @@ static int __init sba_driver_callback(struct parisc_device *dev)
 	proc_create("sba_iommu", 0, root, &sba_proc_fops);
 	proc_create("sba_iommu-bitmap", 0, root, &sba_proc_bitmap_fops);
 #endif
-
-	parisc_has_iommu();
 	return 0;
 }
 
drivers/pci/host/vmd.c +1 -0
index 509893bc3e63..5bb03ad9ed21 100644
@@ -428,6 +428,7 @@ static void vmd_setup_dma_ops(struct vmd_dev *vmd)
 #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
 	ASSIGN_VMD_DMA_OPS(source, dest, get_required_mask);
 #endif
+	dest->is_phys = source->is_phys;
 	add_dma_domain(domain);
 }
 #undef ASSIGN_VMD_DMA_OPS
drivers/scsi/scsi_lib.c +6 -8
index d9ca1dfab154..2644214a92ca 100644
@@ -2105,16 +2105,14 @@ static u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
 
 	if (shost->unchecked_isa_dma)
 		return BLK_BOUNCE_ISA;
-	/*
-	 * Platforms with virtual-DMA translation
-	 * hardware have no practical limit.
-	 */
-	if (!PCI_DMA_BUS_IS_PHYS)
-		return BLK_BOUNCE_ANY;
 
 	host_dev = scsi_get_device(shost);
-	if (host_dev && host_dev->dma_mask)
-		bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
+	if (host_dev) {
+		if (!dma_is_phys(host_dev))
+			return BLK_BOUNCE_ANY;
+		if (host_dev->dma_mask)
+			bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
+	}
 
 	return bounce_limit;
 }
include/asm-generic/pci.h +0 -8
index 830d7659289b..6bb3cd3d695a 100644
@@ -14,12 +14,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 }
 #endif /* HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ */
 
-/*
- * By default, assume that no iommu is in use and that the PCI
- * space is mapped to address physical 0.
- */
-#ifndef PCI_DMA_BUS_IS_PHYS
-#define PCI_DMA_BUS_IS_PHYS	(1)
-#endif
-
 #endif /* _ASM_GENERIC_PCI_H */
include/linux/dma-mapping.h +22 -1
index d84951865be7..e77e2dec4723 100644
@@ -133,7 +133,14 @@ struct dma_map_ops {
 #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
 	u64 (*get_required_mask)(struct device *dev);
 #endif
-	int is_phys;
+
+	/*
+	 * If is_phys is true, the dma_map_ops implementation only does a
+	 * linear mapping from physical to DMA address, and can only address
+	 * memory up to dma_max_pfn().  If is_phys is false DMA is possible
+	 * to any physical address.
+	 */
+	bool is_phys;
 };
 
 extern const struct dma_map_ops dma_noop_ops;
@@ -689,6 +696,20 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)
 	return -EIO;
 }
 
+#ifdef CONFIG_HAS_DMA
+static inline bool dma_is_phys(struct device *dev)
+{
+	const struct dma_map_ops *ops = get_dma_ops(dev);
+
+	return ops && ops->is_phys;
+}
+#else
+static inline bool dma_is_phys(struct device *dev)
+{
+	return false;
+}
+#endif
+
 #ifndef dma_max_pfn
 static inline unsigned long dma_max_pfn(struct device *dev)
 {
lib/dma-noop.c +1 -0
index a10185b0c2d4..c3728a0551f5 100644
@@ -63,6 +63,7 @@ const struct dma_map_ops dma_noop_ops = {
 	.free			= dma_noop_free,
 	.map_page		= dma_noop_map_page,
 	.map_sg			= dma_noop_map_sg,
+	.is_phys		= true,
 };
 
 EXPORT_SYMBOL(dma_noop_ops);
net/core/dev.c +8 -10
index 01ee854454a8..ddf45f9217d4 100644
@@ -2830,6 +2830,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault);
 static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 {
 #ifdef CONFIG_HIGHMEM
+	struct device *pdev = dev->dev.parent;
 	int i;
 
 	if (!(dev->features & NETIF_F_HIGHDMA)) {
@@ -2841,18 +2842,15 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 		}
 	}
 
-	if (PCI_DMA_BUS_IS_PHYS) {
-		struct device *pdev = dev->dev.parent;
+	if (!pdev || !dma_is_phys(pdev))
+		return 0;
 
-		if (!pdev)
-			return 0;
-		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-			dma_addr_t addr = page_to_phys(skb_frag_page(frag));
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		dma_addr_t addr = page_to_phys(skb_frag_page(frag));
 
-			if (!pdev->dma_mask || addr + PAGE_SIZE - 1 > *pdev->dma_mask)
-				return 1;
-		}
+		if (!pdev->dma_mask || addr + PAGE_SIZE - 1 > *pdev->dma_mask)
+			return 1;
 	}
 #endif
 	return 0;
tools/virtio/linux/dma-mapping.h +0 -2
index 1571e24e9494..f91aeb5fe571 100644
@@ -6,8 +6,6 @@
 # error Virtio userspace code does not support CONFIG_HAS_DMA
 #endif
 
-#define PCI_DMA_BUS_IS_PHYS 1
-
 enum dma_data_direction {
 	DMA_BIDIRECTIONAL = 0,
 	DMA_TO_DEVICE = 1,
Signature · 1 line
2.14.2
maintainer Acked-by on v1 5/67
#13 lore raw

Re: [PATCH 05/67] dma-mapping: replace PCI_DMA_BUS_IS_PHYS with a flag in struct dma_map_ops

Quoted 14 lines · Christoph Hellwig

The current PCI_DMA_BUS_IS_PHYS decided if a dma implementation is bound by the dma mask in the device because it directly maps to a physical address range (modulo an offset in the device), or if it is virtualized by an iommu and can map any address (that includes virtual iommus like swiotlb). The problem with this scheme is that it is per-architecture and not per dma_ops instance, and we are growing more and more setups that have multiple different dma operations in use on a single system, for which this scheme can't provide a correct answer. Depending on the architecture that means we either get a false positive or false negative at the moment.

This patch instead extents the is_phys flag in struct dma_map_ops that is currently only used by a few architectures to be used tree wide.

Quoted 6 lines

Note that this means that we now need a struct device parent in the Scsi_Host or netdevice. Every modern driver has these, but there might still be a few outdated legacy drivers out there, which now won't make an intelligent decision.

For m68k:

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

Acked-by on v1 5/67
#14 lore raw

Re: [PATCH 05/67] dma-mapping: replace PCI_DMA_BUS_IS_PHYS with a flag in struct dma_map_ops

In reply to Christoph Hellwig
Quoted 14 lines · Christoph Hellwig

The current PCI_DMA_BUS_IS_PHYS decided if a dma implementation is bound by the dma mask in the device because it directly maps to a physical address range (modulo an offset in the device), or if it is virtualized by an iommu and can map any address (that includes virtual iommus like swiotlb). The problem with this scheme is that it is per-architecture and not per dma_ops instance, and we are growing more and more setups that have multiple different dma operations in use on a single system, for which this scheme can't provide a correct answer. Depending on the architecture that means we either get a false positive or false negative at the moment.

This patch instead extents the is_phys flag in struct dma_map_ops that is currently only used by a few architectures to be used tree wide.

Quoted 6 lines

Note that this means that we now need a struct device parent in the Scsi_Host or netdevice. Every modern driver has these, but there might still be a few outdated legacy drivers out there, which now won't make an intelligent decision.

For the CRIS part:

Quoted 3 lines
---
 arch/cris/arch-v32/drivers/pci/dma.c  |  1 +
 arch/cris/include/asm/pci.h           |  6 ------

/^JN - Jesper Nilsson

Signature · 1 line
               Jesper Nilsson -- [email protected]
#15 lore raw

PATCH 5/67 dma-mapping: replace PCI_DMA_BUS_IS_PHYS with a flag in struct dma_map_ops

In reply to Christoph Hellwig

The current PCI_DMA_BUS_IS_PHYS decided if a dma implementation is bound by the dma mask in the device because it directly maps to a physical address range (modulo an offset in the device), or if it is virtualized by an iommu and can map any address (that includes virtual iommus like swiotlb). The problem with this scheme is that it is per-architecture and not per dma_ops instance, and we are growing more and more setups that have multiple different dma operations in use on a single system, for which this scheme can't provide a correct answer. Depending on the architecture that means we either get a false positive or false negative at the moment.

This patch instead extents the is_phys flag in struct dma_map_ops that is currently only used by a few architectures to be used tree wide.

Note that this means that we now need a struct device parent in the Scsi_Host or netdevice. Every modern driver has these, but there might still be a few outdated legacy drivers out there, which now won't make an intelligent decision.

---
 arch/alpha/include/asm/pci.h          |  5 -----
 arch/alpha/kernel/pci-noop.c          |  1 +
 arch/arc/include/asm/pci.h            |  6 ------
 arch/arc/mm/dma.c                     |  1 +
 arch/arm/include/asm/pci.h            |  7 -------
 arch/arm/mm/dma-mapping-nommu.c       |  1 +
 arch/arm/mm/dma-mapping.c             |  2 ++
 arch/arm64/include/asm/pci.h          |  5 -----
 arch/blackfin/kernel/dma-mapping.c    |  2 ++
 arch/c6x/kernel/dma.c                 |  1 +
 arch/cris/arch-v32/drivers/pci/dma.c  |  1 +
 arch/cris/include/asm/pci.h           |  6 ------
 arch/frv/mb93090-mb00/pci-dma-nommu.c |  1 +
 arch/frv/mb93090-mb00/pci-dma.c       |  1 +
 arch/h8300/include/asm/pci.h          |  2 --
 arch/h8300/kernel/dma.c               |  1 +
 arch/hexagon/kernel/dma.c             |  2 +-
 arch/ia64/hp/common/sba_iommu.c       |  3 ---
 arch/ia64/include/asm/pci.h           | 17 -----------------
 arch/ia64/kernel/setup.c              | 12 ------------
 arch/ia64/sn/kernel/io_common.c       |  5 -----
 arch/m68k/include/asm/pci.h           |  6 ------
 arch/m68k/kernel/dma.c                |  1 +
 arch/metag/kernel/dma.c               |  1 +
 arch/microblaze/include/asm/pci.h     |  6 ------
 arch/microblaze/kernel/dma.c          |  1 +
 arch/mips/include/asm/pci.h           |  7 -------
 arch/mips/mm/dma-default.c            |  1 +
 arch/mn10300/include/asm/pci.h        |  6 ------
 arch/mn10300/mm/dma-alloc.c           |  1 +
 arch/nios2/mm/dma-mapping.c           |  1 +
 arch/openrisc/kernel/dma.c            |  1 +
 arch/parisc/include/asm/pci.h         | 23 -----------------------
 arch/parisc/kernel/pci-dma.c          |  2 ++
 arch/parisc/kernel/setup.c            |  5 -----
 arch/powerpc/include/asm/pci.h        | 18 ------------------
 arch/powerpc/kernel/dma.c             |  1 +
 arch/riscv/include/asm/pci.h          |  3 ---
 arch/s390/include/asm/pci.h           |  2 --
 arch/s390/pci/pci_dma.c               |  3 ---
 arch/sh/include/asm/pci.h             |  6 ------
 arch/sh/kernel/dma-nommu.c            |  2 +-
 arch/sparc/include/asm/pci_32.h       |  4 ----
 arch/sparc/include/asm/pci_64.h       |  6 ------
 arch/sparc/kernel/ioport.c            |  1 +
 arch/tile/include/asm/pci.h           | 14 --------------
 arch/tile/kernel/pci-dma.c            |  2 ++
 arch/x86/include/asm/pci.h            |  2 --
 arch/x86/kernel/pci-nommu.c           |  2 +-
 arch/xtensa/include/asm/pci.h         |  7 -------
 arch/xtensa/kernel/pci-dma.c          |  1 +
 drivers/ide/ide-lib.c                 |  5 ++---
 drivers/ide/ide-probe.c               |  2 +-
 drivers/parisc/ccio-dma.c             |  2 --
 drivers/parisc/sba_iommu.c            |  2 --
 drivers/pci/host/vmd.c                |  1 +
 drivers/scsi/scsi_lib.c               | 14 ++++++--------
 include/asm-generic/pci.h             |  8 --------
 include/linux/dma-mapping.h           | 23 ++++++++++++++++++++++-
 lib/dma-noop.c                        |  1 +
 net/core/dev.c                        | 18 ++++++++----------
 tools/virtio/linux/dma-mapping.h      |  2 --
 62 files changed, 70 insertions(+), 226 deletions(-)
arch/alpha/include/asm/pci.h +0 -5
index b9ec55351924..cf6bc1e64d66 100644
@@ -56,11 +56,6 @@ struct pci_controller {
 
 /* IOMMU controls.  */
 
-/* The PCI address space does not equal the physical memory address space.
-   The networking and block device layers use this boolean for bounce buffer
-   decisions.  */
-#define PCI_DMA_BUS_IS_PHYS  0
-
 /* TODO: integrate with include/asm-generic/pci.h ? */
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
arch/alpha/kernel/pci-noop.c +1 -0
index b995987b1557..d3208254b269 100644
@@ -132,6 +132,7 @@ const struct dma_map_ops alpha_noop_ops = {
 	.map_sg			= dma_noop_map_sg,
 	.mapping_error		= dma_noop_mapping_error,
 	.dma_supported		= alpha_noop_supported,
+	.is_phys		= true,
 };
 
 const struct dma_map_ops *dma_ops = &alpha_noop_ops;
arch/arc/include/asm/pci.h +0 -6
index ba56c23c1b20..4ff53c041c64 100644
@@ -16,12 +16,6 @@
 #define PCIBIOS_MIN_MEM 0x100000
 
 #define pcibios_assign_all_busses()	1
-/*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	1
 
 #endif /* __KERNEL__ */
 
arch/arc/mm/dma.c +1 -0
index e9d93604ad0f..fad18261ef6a 100644
@@ -274,5 +274,6 @@ const struct dma_map_ops arc_dma_ops = {
 	.sync_sg_for_cpu	= arc_dma_sync_sg_for_cpu,
 	.sync_sg_for_device	= arc_dma_sync_sg_for_device,
 	.dma_supported		= arc_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(arc_dma_ops);
arch/arm/include/asm/pci.h +0 -7
index 960d9dc4f380..05b2eb2dc76f 100644
@@ -22,13 +22,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif /* CONFIG_PCI_DOMAINS */
 
-/*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
 #define HAVE_PCI_MMAP
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE
 
arch/arm/mm/dma-mapping-nommu.c +1 -0
index 6db5fc26d154..1cced700e45a 100644
@@ -208,6 +208,7 @@ const struct dma_map_ops arm_nommu_dma_ops = {
 	.sync_single_for_cpu	= arm_nommu_dma_sync_single_for_cpu,
 	.sync_sg_for_device	= arm_nommu_dma_sync_sg_for_device,
 	.sync_sg_for_cpu	= arm_nommu_dma_sync_sg_for_cpu,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(arm_nommu_dma_ops);
 
arch/arm/mm/dma-mapping.c +2 -0
index ada8eb206a90..8e120e2d9cac 100644
@@ -200,6 +200,7 @@ const struct dma_map_ops arm_dma_ops = {
 	.sync_sg_for_device	= arm_dma_sync_sg_for_device,
 	.mapping_error		= arm_dma_mapping_error,
 	.dma_supported		= arm_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(arm_dma_ops);
 
@@ -220,6 +221,7 @@ const struct dma_map_ops arm_coherent_dma_ops = {
 	.map_sg			= arm_dma_map_sg,
 	.mapping_error		= arm_dma_mapping_error,
 	.dma_supported		= arm_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(arm_coherent_dma_ops);
 
arch/arm64/include/asm/pci.h +0 -5
index 8747f7c5e0e7..9e690686e8aa 100644
@@ -18,11 +18,6 @@
 #define pcibios_assign_all_busses() \
 	(pci_has_flag(PCI_REASSIGN_ALL_BUS))
 
-/*
- * PCI address space differs from physical memory address space
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE	1
 
 extern int isa_dma_bridge_buggy;
arch/blackfin/kernel/dma-mapping.c +2 -0
index 477bb29a7987..362902a2a418 100644
@@ -168,5 +168,7 @@ const struct dma_map_ops bfin_dma_ops = {
 
 	.sync_single_for_device	= bfin_dma_sync_single_for_device,
 	.sync_sg_for_device	= bfin_dma_sync_sg_for_device,
+
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(bfin_dma_ops);
arch/c6x/kernel/dma.c +1 -0
index 9fff8be75f58..a526dddeeac1 100644
@@ -134,6 +134,7 @@ const struct dma_map_ops c6x_dma_ops = {
 	.sync_single_for_cpu	= c6x_dma_sync_single_for_cpu,
 	.sync_sg_for_device	= c6x_dma_sync_sg_for_device,
 	.sync_sg_for_cpu	= c6x_dma_sync_sg_for_cpu,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(c6x_dma_ops);
 
arch/cris/arch-v32/drivers/pci/dma.c +1 -0
index dbbd3816cc0b..aa16ce27e036 100644
@@ -76,5 +76,6 @@ const struct dma_map_ops v32_dma_ops = {
 	.map_page		= v32_dma_map_page,
 	.map_sg                 = v32_dma_map_sg,
 	.dma_supported		= v32_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(v32_dma_ops);
arch/cris/include/asm/pci.h +0 -6
index dcfef6407ae6..eb1f7f172f4b 100644
@@ -27,12 +27,6 @@
 #include <linux/string.h>
 #include <asm/io.h>
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 #define HAVE_PCI_MMAP
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE
 
arch/frv/mb93090-mb00/pci-dma-nommu.c +1 -0
index 4a96de7f0af4..d58d701619e5 100644
@@ -172,5 +172,6 @@ const struct dma_map_ops frv_dma_ops = {
 	.sync_single_for_device	= frv_dma_sync_single_for_device,
 	.sync_sg_for_device	= frv_dma_sync_sg_for_device,
 	.dma_supported		= frv_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(frv_dma_ops);
arch/frv/mb93090-mb00/pci-dma.c +1 -0
index e7130abc0dae..8c2e9a40e57e 100644
@@ -114,5 +114,6 @@ const struct dma_map_ops frv_dma_ops = {
 	.sync_single_for_device	= frv_dma_sync_single_for_device,
 	.sync_sg_for_device	= frv_dma_sync_sg_for_device,
 	.dma_supported		= frv_dma_supported,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(frv_dma_ops);
arch/h8300/include/asm/pci.h +0 -2
index 7c9e55d62215..d4d345a52092 100644
@@ -15,6 +15,4 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
 	/* We don't do dynamic PCI IRQ allocation */
 }
 
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 #endif /* _ASM_H8300_PCI_H */
arch/h8300/kernel/dma.c +1 -0
index 225dd0a188dc..0e92214310c4 100644
@@ -65,5 +65,6 @@ const struct dma_map_ops h8300_dma_map_ops = {
 	.free = dma_free,
 	.map_page = map_page,
 	.map_sg = map_sg,
+	.is_phys = true,
 };
 EXPORT_SYMBOL(h8300_dma_map_ops);
arch/hexagon/kernel/dma.c +1 -1
index 546792d176a4..3683bb9c05a2 100644
@@ -207,7 +207,7 @@ const struct dma_map_ops hexagon_dma_ops = {
 	.sync_single_for_cpu = hexagon_sync_single_for_cpu,
 	.sync_single_for_device = hexagon_sync_single_for_device,
 	.mapping_error	= hexagon_mapping_error,
-	.is_phys	= 1,
+	.is_phys	= true,
 };
 
 void __init hexagon_dma_init(void)
arch/ia64/hp/common/sba_iommu.c +0 -3
index aec4a3354abe..6f05aba9012f 100644
@@ -1845,9 +1845,6 @@ static void ioc_init(unsigned long hpa, struct ioc *ioc)
 	ioc_resource_init(ioc);
 	ioc_sac_init(ioc);
 
-	if ((long) ~iovp_mask > (long) ia64_max_iommu_merge_mask)
-		ia64_max_iommu_merge_mask = ~iovp_mask;
-
 	printk(KERN_INFO PFX
 		"%s %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
 		ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
arch/ia64/include/asm/pci.h +0 -17
index b1d04e8bafc8..780e8744ba85 100644
@@ -30,23 +30,6 @@ struct pci_vector_struct {
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
 
-/*
- * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct
- * correspondence between device bus addresses and CPU physical addresses.
- * Platforms with a hardware I/O MMU _must_ turn this off to suppress the
- * bounce buffer handling code in the block and network device layers.
- * Platforms with separate bus address spaces _must_ turn this off and provide
- * a device DMA mapping implementation that takes care of the necessary
- * address translation.
- *
- * For now, the ia64 platforms which may have separate/multiple bus address
- * spaces all have I/O MMUs which support the merging of physically
- * discontiguous buffers, so we can use that as the sole factor to determine
- * the setting of PCI_DMA_BUS_IS_PHYS.
- */
-extern unsigned long ia64_max_iommu_merge_mask;
-#define PCI_DMA_BUS_IS_PHYS	(ia64_max_iommu_merge_mask == ~0UL)
-
 #define HAVE_PCI_MMAP
 #define ARCH_GENERIC_PCI_MMAP_RESOURCE
 #define arch_can_pci_mmap_wc()	1
arch/ia64/kernel/setup.c +0 -12
index dee56bcb993d..ad43cbf70628 100644
@@ -123,18 +123,6 @@ unsigned long ia64_i_cache_stride_shift = ~0;
 #define	CACHE_STRIDE_SHIFT	5
 unsigned long ia64_cache_stride_shift = ~0;
 
-/*
- * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
- * mask specifies a mask of address bits that must be 0 in order for two buffers to be
- * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start
- * address of the second buffer must be aligned to (merge_mask+1) in order to be
- * mergeable).  By default, we assume there is no I/O MMU which can merge physically
- * discontiguous buffers, so we set the merge_mask to ~0UL, which corresponds to a iommu
- * page-size of 2^64.
- */
-unsigned long ia64_max_iommu_merge_mask = ~0UL;
-EXPORT_SYMBOL(ia64_max_iommu_merge_mask);
-
 /*
  * We use a special marker for the end of memory and it uses the extra (+1) slot
  */
arch/ia64/sn/kernel/io_common.c +0 -5
index 11f2275570fb..8479e9a7ce16 100644
@@ -480,11 +480,6 @@ sn_io_early_init(void)
 	tioca_init_provider();
 	tioce_init_provider();
 
-	/*
-	 * This is needed to avoid bounce limit checks in the blk layer
-	 */
-	ia64_max_iommu_merge_mask = ~PAGE_MASK;
-
 	sn_irq_lh_init();
 	INIT_LIST_HEAD(&sn_sysdata_list);
 	sn_init_cpei_timer();
arch/m68k/include/asm/pci.h +0 -6
index ef26fae8cf0b..5a4bc223743b 100644
@@ -4,12 +4,6 @@
 
 #include <asm-generic/pci.h>
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 #define	pcibios_assign_all_busses()	1
 
 #define	PCIBIOS_MIN_IO		0x00000100
arch/m68k/kernel/dma.c +1 -0
index 87ef73a93856..e0167418072b 100644
@@ -165,5 +165,6 @@ const struct dma_map_ops m68k_dma_ops = {
 	.map_sg			= m68k_dma_map_sg,
 	.sync_single_for_device	= m68k_dma_sync_single_for_device,
 	.sync_sg_for_device	= m68k_dma_sync_sg_for_device,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(m68k_dma_ops);
arch/metag/kernel/dma.c +1 -0
index f0ab3a498328..16cb4df51b8a 100644
@@ -584,5 +584,6 @@ const struct dma_map_ops metag_dma_ops = {
 	.sync_single_for_cpu	= metag_dma_sync_single_for_cpu,
 	.sync_sg_for_cpu	= metag_dma_sync_sg_for_cpu,
 	.mmap			= metag_dma_mmap,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(metag_dma_ops);
arch/microblaze/include/asm/pci.h +0 -6
index 114b93488193..00478965f932 100644
@@ -61,12 +61,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 
 #define HAVE_PCI_LEGACY	1
 
-/* The PCI address space does equal the physical memory
- * address space (no IOMMU).  The IDE and SCSI device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
 extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
arch/microblaze/kernel/dma.c +1 -0
index 990bf9ea0ec6..2a9a0ec14c46 100644
@@ -216,6 +216,7 @@ const struct dma_map_ops dma_direct_ops = {
 	.sync_single_for_device		= dma_direct_sync_single_for_device,
 	.sync_sg_for_cpu		= dma_direct_sync_sg_for_cpu,
 	.sync_sg_for_device		= dma_direct_sync_sg_for_device,
+	.is_phys	= true,
 };
 EXPORT_SYMBOL(dma_direct_ops);
 
arch/mips/include/asm/pci.h +0 -7
index 2339f42f047a..436099883022 100644
@@ -121,13 +121,6 @@ extern unsigned long PCIBIOS_MIN_MEM;
 #include <linux/string.h>
 #include <asm/io.h>
 
-/*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
 #ifdef CONFIG_PCI_DOMAINS_GENERIC
 static inline int pci_proc_domain(struct pci_bus *bus)
 {
arch/mips/mm/dma-default.c +1 -0
index e3e94d05f0fd..3cd93e0c7a29 100644
@@ -407,6 +407,7 @@ static const struct dma_map_ops mips_default_dma_map_ops = {
 	.mapping_error = mips_dma_mapping_error,
 	.dma_supported = mips_dma_supported,
 	.cache_sync = mips_dma_cache_sync,
+	.is_phys = true,
 };
 
 const struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
arch/mn10300/include/asm/pci.h +0 -6
index 5b75a1b2c4f6..6132966bdf30 100644
@@ -57,12 +57,6 @@ extern void unit_pci_init(void);
 #include <linux/string.h>
 #include <asm/io.h>
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 /* Return the index of the PCI controller for device. */
 static inline int pci_controller_num(struct pci_dev *dev)
 {
arch/mn10300/mm/dma-alloc.c +1 -0
index 86108d2496b3..55876a87c247 100644
@@ -128,4 +128,5 @@ const struct dma_map_ops mn10300_dma_ops = {
 	.map_sg			= mn10300_dma_map_sg,
 	.sync_single_for_device	= mn10300_dma_sync_single_for_device,
 	.sync_sg_for_device	= mn10300_dma_sync_sg_for_device,
+	.is_phys		= true,
 };
arch/nios2/mm/dma-mapping.c +1 -0
index 7040c1adbb5e..599bcc09c9e7 100644
@@ -203,5 +203,6 @@ const struct dma_map_ops nios2_dma_ops = {
 	.sync_single_for_cpu	= nios2_dma_sync_single_for_cpu,
 	.sync_sg_for_cpu	= nios2_dma_sync_sg_for_cpu,
 	.sync_sg_for_device	= nios2_dma_sync_sg_for_device,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(nios2_dma_ops);
arch/openrisc/kernel/dma.c +1 -0
index a945f00011b4..7faad429d3dc 100644
@@ -245,6 +245,7 @@ const struct dma_map_ops or1k_dma_map_ops = {
 	.unmap_sg = or1k_unmap_sg,
 	.sync_single_for_cpu = or1k_sync_single_for_cpu,
 	.sync_single_for_device = or1k_sync_single_for_device,
+	.is_phys = true,
 };
 EXPORT_SYMBOL(or1k_dma_map_ops);
 
arch/parisc/include/asm/pci.h +0 -23
index 96b7deec512d..3328fd17c19d 100644
@@ -87,29 +87,6 @@ struct pci_hba_data {
 #define PCI_F_EXTEND		0UL
 #endif /* !CONFIG_64BIT */
 
-/*
- * If the PCI device's view of memory is the same as the CPU's view of memory,
- * PCI_DMA_BUS_IS_PHYS is true.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#ifdef CONFIG_PA20
-/* All PA-2.0 machines have an IOMMU. */
-#define PCI_DMA_BUS_IS_PHYS	0
-#define parisc_has_iommu()	do { } while (0)
-#else
-
-#if defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA)
-extern int parisc_bus_is_phys; 	/* in arch/parisc/kernel/setup.c */
-#define PCI_DMA_BUS_IS_PHYS	parisc_bus_is_phys
-#define parisc_has_iommu()	do { parisc_bus_is_phys = 0; } while (0)
-#else
-#define PCI_DMA_BUS_IS_PHYS	1
-#define parisc_has_iommu()	do { } while (0)
-#endif
-
-#endif	/* !CONFIG_PA20 */
-
-
 /*
 ** Most PCI devices (eg Tulip, NCR720) also export the same registers
 ** to both MMIO and I/O port space.  Due to poor performance of I/O Port
arch/parisc/kernel/pci-dma.c +2 -0
index c0dfd892f70c..6ad9aed3d025 100644
@@ -591,6 +591,7 @@ const struct dma_map_ops pcxl_dma_ops = {
 	.sync_sg_for_cpu =	pa11_dma_sync_sg_for_cpu,
 	.sync_sg_for_device =	pa11_dma_sync_sg_for_device,
 	.cache_sync =		pa11_dma_cache_sync,
+	.is_phys =		true,
 };
 
 static void *pcx_dma_alloc(struct device *dev, size_t size,
@@ -628,4 +629,5 @@ const struct dma_map_ops pcx_dma_ops = {
 	.sync_sg_for_cpu =	pa11_dma_sync_sg_for_cpu,
 	.sync_sg_for_device =	pa11_dma_sync_sg_for_device,
 	.cache_sync =		pa11_dma_cache_sync,
+	.is_phys =		true,
 };
arch/parisc/kernel/setup.c +0 -5
index 0e9675f857a5..8d3a7b80ac42 100644
@@ -58,11 +58,6 @@ struct proc_dir_entry * proc_runway_root __read_mostly = NULL;
 struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
 struct proc_dir_entry * proc_mckinley_root __read_mostly = NULL;
 
-#if !defined(CONFIG_PA20) && (defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA))
-int parisc_bus_is_phys __read_mostly = 1;	/* Assume no IOMMU is present */
-EXPORT_SYMBOL(parisc_bus_is_phys);
-#endif
-
 void __init setup_cmdline(char **cmdline_p)
 {
 	extern unsigned int boot_args[];
arch/powerpc/include/asm/pci.h +0 -18
index 8dc32eacc97c..04c1347e2c51 100644
@@ -91,24 +91,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 
 #define HAVE_PCI_LEGACY	1
 
-#ifdef CONFIG_PPC64
-
-/* The PCI address space does not equal the physical memory address
- * space (we have an IOMMU).  The IDE and SCSI device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
-#else /* 32-bit */
-
-/* The PCI address space does equal the physical memory
- * address space (no IOMMU).  The IDE and SCSI device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
-#endif /* CONFIG_PPC64 */
-
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
 extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
arch/powerpc/kernel/dma.c +1 -0
index 4194bbbbdb10..df0e7bb97ab5 100644
@@ -290,6 +290,7 @@ const struct dma_map_ops dma_direct_ops = {
 	.sync_sg_for_cpu 		= dma_direct_sync_sg,
 	.sync_sg_for_device 		= dma_direct_sync_sg,
 #endif
+	.is_phys			= true,
 };
 EXPORT_SYMBOL(dma_direct_ops);
 
arch/riscv/include/asm/pci.h +0 -3
index 0f2fc9ef20fc..b3638c505728 100644
@@ -26,9 +26,6 @@
 /* RISC-V shim does not initialize PCI bus */
 #define pcibios_assign_all_busses() 1
 
-/* We do not have an IOMMU */
-#define PCI_DMA_BUS_IS_PHYS 1
-
 extern int isa_dma_bridge_buggy;
 
 #ifdef CONFIG_PCI
arch/s390/include/asm/pci.h +0 -2
index 12fe3591034f..94f8db468c9b 100644
@@ -2,8 +2,6 @@
 #ifndef __ASM_S390_PCI_H
 #define __ASM_S390_PCI_H
 
-/* must be set before including asm-generic/pci.h */
-#define PCI_DMA_BUS_IS_PHYS (0)
 /* must be set before including pci_clp.h */
 #define PCI_BAR_COUNT	6
 
arch/s390/pci/pci_dma.c +0 -3
index f7aa5a77827e..90826e2010da 100644
@@ -668,9 +668,6 @@ const struct dma_map_ops s390_pci_dma_ops = {
 	.map_page	= s390_dma_map_pages,
 	.unmap_page	= s390_dma_unmap_pages,
 	.mapping_error	= s390_mapping_error,
-	/* if we support direct DMA this must be conditional */
-	.is_phys	= 0,
-	/* dma_supported is unconditionally true without a callback */
 };
 EXPORT_SYMBOL_GPL(s390_pci_dma_ops);
 
arch/sh/include/asm/pci.h +0 -6
index 0033f0df2b3b..10a36b1cf2ea 100644
@@ -71,12 +71,6 @@ extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM;
  * SuperH has everything mapped statically like x86.
  */
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(dma_ops->is_phys)
-
 #ifdef CONFIG_PCI
 /*
  * None of the SH PCI controllers support MWI, it is always treated as a
arch/sh/kernel/dma-nommu.c +1 -1
index 62b485107eae..a2ef7f19610d 100644
@@ -75,7 +75,7 @@ const struct dma_map_ops nommu_dma_ops = {
 	.sync_single_for_device	= nommu_sync_single_for_device,
 	.sync_sg_for_device	= nommu_sync_sg_for_device,
 #endif
-	.is_phys		= 1,
+	.is_phys		= true,
 };
 
 void __init no_iommu_init(void)
arch/sparc/include/asm/pci_32.h +0 -4
index 98917e48727d..cfc0ee9476c6 100644
@@ -17,10 +17,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-/* Dynamic DMA mapping stuff.
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
 #endif /* __KERNEL__ */
 
 #ifndef CONFIG_LEON_PCI
arch/sparc/include/asm/pci_64.h +0 -6
index 671274e36cfa..fac77813402c 100644
@@ -17,12 +17,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-/* The PCI address space does not equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(0)
-
 /* PCI IOMMU mapping bypass support. */
 
 /* PCI 64-bit addressing works for all slots on all controller
arch/sparc/kernel/ioport.c +1 -0
index 7eeef80c02f7..a401e8e0579d 100644
@@ -656,6 +656,7 @@ const struct dma_map_ops pci32_dma_ops = {
 	.sync_single_for_device	= pci32_sync_single_for_device,
 	.sync_sg_for_cpu	= pci32_sync_sg_for_cpu,
 	.sync_sg_for_device	= pci32_sync_sg_for_device,
+	.is_phys		= true,
 };
 EXPORT_SYMBOL(pci32_dma_ops);
 
arch/tile/include/asm/pci.h +0 -14
index fe3de505b024..8b910e3f0620 100644
@@ -52,13 +52,6 @@ static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
 
 #define	TILE_NUM_PCIE	2
 
-/*
- * The hypervisor maps the entirety of CPA-space as bus addresses, so
- * bus addresses are physical addresses.  The networking and block
- * device layers use this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     1
-
 /* generic pci stuff */
 #include <asm-generic/pci.h>
 
@@ -185,13 +178,6 @@ extern int num_trio_shims;
 
 extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
 
-/*
- * The PCI address space does not equal the physical memory address
- * space (we have an IOMMU). The IDE and SCSI device layers use this
- * boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS     0
-
 #endif /* __tilegx__ */
 
 int __init tile_pci_init(void);
arch/tile/kernel/pci-dma.c +2 -0
index f2abedc8a080..9072e2c25e59 100644
@@ -328,6 +328,7 @@ static const struct dma_map_ops tile_default_dma_map_ops = {
 	.sync_single_for_device = tile_dma_sync_single_for_device,
 	.sync_sg_for_cpu = tile_dma_sync_sg_for_cpu,
 	.sync_sg_for_device = tile_dma_sync_sg_for_device,
+	.is_phys = true,
 };
 
 const struct dma_map_ops *tile_dma_map_ops = &tile_default_dma_map_ops;
@@ -501,6 +502,7 @@ static const struct dma_map_ops tile_pci_default_dma_map_ops = {
 	.sync_single_for_device = tile_pci_dma_sync_single_for_device,
 	.sync_sg_for_cpu = tile_pci_dma_sync_sg_for_cpu,
 	.sync_sg_for_device = tile_pci_dma_sync_sg_for_device,
+	.is_phys = true,
 };
 
 const struct dma_map_ops *gx_pci_dma_map_ops = &tile_pci_default_dma_map_ops;
arch/x86/include/asm/pci.h +0 -2
index d32175e30259..fecde74ff549 100644
@@ -118,8 +118,6 @@ void native_restore_msi_irqs(struct pci_dev *dev);
 #define native_teardown_msi_irq		NULL
 #endif
 
-#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-
 #endif  /* __KERNEL__ */
 
 #ifdef CONFIG_X86_64
arch/x86/kernel/pci-nommu.c +1 -1
index c78df78b5ccd..8ac9d1fe0373 100644
@@ -84,7 +84,7 @@ const struct dma_map_ops nommu_dma_ops = {
 	.free			= dma_generic_free_coherent,
 	.map_sg			= nommu_map_sg,
 	.map_page		= nommu_map_page,
-	.is_phys		= 1,
 	.mapping_error		= nommu_mapping_error,
 	.dma_supported		= x86_dma_supported,
+	.is_phys		= true,
 };
arch/xtensa/include/asm/pci.h +0 -7
index 5c83798e3b2e..7949349294c7 100644
@@ -37,13 +37,6 @@ extern struct pci_controller* pcibios_alloc_controller(void);
 #include <linux/string.h>
 #include <asm/io.h>
 
-/* The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce buffer
- * decisions.
- */
-
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
 #define HAVE_PCI_MMAP		1
 #define arch_can_pci_mmap_io()	1
arch/xtensa/kernel/pci-dma.c +1 -0
index 623720a11143..4a51996d2919 100644
@@ -239,6 +239,7 @@ const struct dma_map_ops xtensa_dma_map_ops = {
 	.sync_sg_for_cpu = xtensa_sync_sg_for_cpu,
 	.sync_sg_for_device = xtensa_sync_sg_for_device,
 	.mapping_error = xtensa_dma_mapping_error,
+	.is_phys = true,
 };
 EXPORT_SYMBOL(xtensa_dma_map_ops);
 
drivers/ide/ide-lib.c +2 -3
index e1180fa46196..0cdd661ddee0 100644
@@ -17,13 +17,12 @@
 
 void ide_toggle_bounce(ide_drive_t *drive, int on)
 {
+	struct device *dev = drive->hwif ? drive->hwif->dev : NULL;
 	u64 addr = BLK_BOUNCE_HIGH;	/* dma64_addr_t */
 
-	if (!PCI_DMA_BUS_IS_PHYS) {
+	if (dev && !dma_is_phys(dev)) {
 		addr = BLK_BOUNCE_ANY;
 	} else if (on && drive->media == ide_disk) {
-		struct device *dev = drive->hwif->dev;
-
 		if (dev && dev->dma_mask)
 			addr = *dev->dma_mask;
 	}
drivers/ide/ide-probe.c +1 -1
index 17fd55af4d92..7fe4d751e6cf 100644
@@ -796,7 +796,7 @@ static int ide_init_queue(ide_drive_t *drive)
 	 * This will be fixed once we teach pci_map_sg() about our boundary
 	 * requirements, hopefully soon. *FIXME*
 	 */
-	if (!PCI_DMA_BUS_IS_PHYS)
+	if (hwif->dev && !dma_is_phys(hwif->dev))
 		max_sg_entries >>= 1;
 #endif /* CONFIG_PCI */
 
drivers/parisc/ccio-dma.c +0 -2
index acba1f56af3e..2b129d8525d5 100644
@@ -1596,8 +1596,6 @@ static int __init ccio_probe(struct parisc_device *dev)
 	}
 #endif
 	ioc_count++;
-
-	parisc_has_iommu();
 	return 0;
 }
 
drivers/parisc/sba_iommu.c +0 -2
index 0a9c762a70fa..a58c586ebd81 100644
@@ -2017,8 +2017,6 @@ static int __init sba_driver_callback(struct parisc_device *dev)
 	proc_create("sba_iommu", 0, root, &sba_proc_fops);
 	proc_create("sba_iommu-bitmap", 0, root, &sba_proc_bitmap_fops);
 #endif
-
-	parisc_has_iommu();
 	return 0;
 }
 
drivers/pci/host/vmd.c +1 -0
index 509893bc3e63..5bb03ad9ed21 100644
@@ -428,6 +428,7 @@ static void vmd_setup_dma_ops(struct vmd_dev *vmd)
 #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
 	ASSIGN_VMD_DMA_OPS(source, dest, get_required_mask);
 #endif
+	dest->is_phys = source->is_phys;
 	add_dma_domain(domain);
 }
 #undef ASSIGN_VMD_DMA_OPS
drivers/scsi/scsi_lib.c +6 -8
index d9ca1dfab154..2644214a92ca 100644
@@ -2105,16 +2105,14 @@ static u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
 
 	if (shost->unchecked_isa_dma)
 		return BLK_BOUNCE_ISA;
-	/*
-	 * Platforms with virtual-DMA translation
-	 * hardware have no practical limit.
-	 */
-	if (!PCI_DMA_BUS_IS_PHYS)
-		return BLK_BOUNCE_ANY;
 
 	host_dev = scsi_get_device(shost);
-	if (host_dev && host_dev->dma_mask)
-		bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
+	if (host_dev) {
+		if (!dma_is_phys(host_dev))
+			return BLK_BOUNCE_ANY;
+		if (host_dev->dma_mask)
+			bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
+	}
 
 	return bounce_limit;
 }
include/asm-generic/pci.h +0 -8
index 830d7659289b..6bb3cd3d695a 100644
@@ -14,12 +14,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 }
 #endif /* HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ */
 
-/*
- * By default, assume that no iommu is in use and that the PCI
- * space is mapped to address physical 0.
- */
-#ifndef PCI_DMA_BUS_IS_PHYS
-#define PCI_DMA_BUS_IS_PHYS	(1)
-#endif
-
 #endif /* _ASM_GENERIC_PCI_H */
include/linux/dma-mapping.h +22 -1
index d84951865be7..e77e2dec4723 100644
@@ -133,7 +133,14 @@ struct dma_map_ops {
 #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
 	u64 (*get_required_mask)(struct device *dev);
 #endif
-	int is_phys;
+
+	/*
+	 * If is_phys is true, the dma_map_ops implementation only does a
+	 * linear mapping from physical to DMA address, and can only address
+	 * memory up to dma_max_pfn().  If is_phys is false DMA is possible
+	 * to any physical address.
+	 */
+	bool is_phys;
 };
 
 extern const struct dma_map_ops dma_noop_ops;
@@ -689,6 +696,20 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)
 	return -EIO;
 }
 
+#ifdef CONFIG_HAS_DMA
+static inline bool dma_is_phys(struct device *dev)
+{
+	const struct dma_map_ops *ops = get_dma_ops(dev);
+
+	return ops && ops->is_phys;
+}
+#else
+static inline bool dma_is_phys(struct device *dev)
+{
+	return false;
+}
+#endif
+
 #ifndef dma_max_pfn
 static inline unsigned long dma_max_pfn(struct device *dev)
 {
lib/dma-noop.c +1 -0
index a10185b0c2d4..c3728a0551f5 100644
@@ -63,6 +63,7 @@ const struct dma_map_ops dma_noop_ops = {
 	.free			= dma_noop_free,
 	.map_page		= dma_noop_map_page,
 	.map_sg			= dma_noop_map_sg,
+	.is_phys		= true,
 };
 
 EXPORT_SYMBOL(dma_noop_ops);
net/core/dev.c +8 -10
index 01ee854454a8..ddf45f9217d4 100644
@@ -2830,6 +2830,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault);
 static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 {
 #ifdef CONFIG_HIGHMEM
+	struct device *pdev = dev->dev.parent;
 	int i;
 
 	if (!(dev->features & NETIF_F_HIGHDMA)) {
@@ -2841,18 +2842,15 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 		}
 	}
 
-	if (PCI_DMA_BUS_IS_PHYS) {
-		struct device *pdev = dev->dev.parent;
+	if (!pdev || !dma_is_phys(pdev))
+		return 0;
 
-		if (!pdev)
-			return 0;
-		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-			dma_addr_t addr = page_to_phys(skb_frag_page(frag));
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		dma_addr_t addr = page_to_phys(skb_frag_page(frag));
 
-			if (!pdev->dma_mask || addr + PAGE_SIZE - 1 > *pdev->dma_mask)
-				return 1;
-		}
+		if (!pdev->dma_mask || addr + PAGE_SIZE - 1 > *pdev->dma_mask)
+			return 1;
 	}
 #endif
 	return 0;
tools/virtio/linux/dma-mapping.h +0 -2
index 1571e24e9494..f91aeb5fe571 100644
@@ -6,8 +6,6 @@
 # error Virtio userspace code does not support CONFIG_HAS_DMA
 #endif
 
-#define PCI_DMA_BUS_IS_PHYS 1
-
 enum dma_data_direction {
 	DMA_BIDIRECTIONAL = 0,
 	DMA_TO_DEVICE = 1,
Signature · 1 line
2.14.2
#16 lore raw

PATCH 6/67 hexagon: remove unused flush_write_buffers definition

In reply to Christoph Hellwig
---
 arch/hexagon/include/asm/io.h | 2 --
 1 file changed, 2 deletions(-)
arch/hexagon/include/asm/io.h +0 -2
index 66f5e9a61efc..9e8621d94ee9 100644
@@ -330,8 +330,6 @@ static inline void outsl(unsigned long port, const void *buffer, int count)
 	}
 }
 
-#define flush_write_buffers() do { } while (0)
-
 #endif /* __KERNEL__ */
 
 #endif
Signature · 1 line
2.14.2
Acked-by on v1 6/67
#17 lore raw

Re: [PATCH 06/67] hexagon: remove unused flush_write_buffers definition

Quoted 21 lines · Christoph Hellwig
---
 arch/hexagon/include/asm/io.h | 2 --
 1 file changed, 2 deletions(-)
arch/hexagon/include/asm/io.h +0 -2
index 66f5e9a61efc..9e8621d94ee9 100644
@@ -330,8 +330,6 @@ static inline void outsl(unsigned long port, const void *buffer, int count)
 	}
 }
 
-#define flush_write_buffers() do { } while (0)
-
 #endif /* __KERNEL__ */
 
 #endif
Signature · 1 line
2.14.2

For Hexagon:

Signature · 3 lines
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, 
a Linux Foundation Collaborative Project
Acked-by on v1 6/67
#18 lore raw

Re: [PATCH 06/67] hexagon: remove unused flush_write_buffers definition

In reply to Christoph Hellwig
Quoted 21 lines · Christoph Hellwig
---
 arch/hexagon/include/asm/io.h | 2 --
 1 file changed, 2 deletions(-)
arch/hexagon/include/asm/io.h +0 -2
index 66f5e9a61efc..9e8621d94ee9 100644
@@ -330,8 +330,6 @@ static inline void outsl(unsigned long port, const void *buffer, int count)
 	}
 }
 
-#define flush_write_buffers() do { } while (0)
-
 #endif /* __KERNEL__ */
 
 #endif
Signature · 1 line
2.14.2

For Hexagon:

Signature · 3 lines
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, 
a Linux Foundation Collaborative Project
#19 lore raw

PATCH 6/67 hexagon: remove unused flush_write_buffers definition

In reply to Christoph Hellwig
---
 arch/hexagon/include/asm/io.h | 2 --
 1 file changed, 2 deletions(-)
arch/hexagon/include/asm/io.h +0 -2
index 66f5e9a61efc..9e8621d94ee9 100644
@@ -330,8 +330,6 @@ static inline void outsl(unsigned long port, const void *buffer, int count)
 	}
 }
 
-#define flush_write_buffers() do { } while (0)
-
 #endif /* __KERNEL__ */
 
 #endif
Signature · 1 line
2.14.2
#20 lore raw

PATCH 7/67 m32r: remove unused flush_write_buffers definition

In reply to Christoph Hellwig
---
 arch/m32r/include/asm/io.h | 2 --
 1 file changed, 2 deletions(-)
arch/m32r/include/asm/io.h +0 -2
index 1b653bb16f9a..a4272d8f0d9c 100644
@@ -191,8 +191,6 @@ static inline void _writel(unsigned long l, unsigned long addr)
 
 #define mmiowb()
 
-#define flush_write_buffers() do { } while (0)  /* M32R_FIXME */
-
 static inline void
 memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
Signature · 1 line
2.14.2
#21 lore raw

PATCH 7/67 m32r: remove unused flush_write_buffers definition

In reply to Christoph Hellwig
---
 arch/m32r/include/asm/io.h | 2 --
 1 file changed, 2 deletions(-)
arch/m32r/include/asm/io.h +0 -2
index 1b653bb16f9a..a4272d8f0d9c 100644
@@ -191,8 +191,6 @@ static inline void _writel(unsigned long l, unsigned long addr)
 
 #define mmiowb()
 
-#define flush_write_buffers() do { } while (0)  /* M32R_FIXME */
-
 static inline void
 memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
Signature · 1 line
2.14.2
#22 lore raw

PATCH 8/67 powerpc: remove unused flush_write_buffers definition

In reply to Christoph Hellwig
---
 arch/powerpc/include/asm/dma-mapping.h | 3 ---
 1 file changed, 3 deletions(-)
arch/powerpc/include/asm/dma-mapping.h +0 -3
index 5a6cbe11db6f..592c7f418aa0 100644
@@ -107,9 +107,6 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
 		dev->archdata.dma_offset = off;
 }
 
-/* this will be removed soon */
-#define flush_write_buffers()
-
 #define HAVE_ARCH_DMA_SET_MASK 1
 extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
Signature · 1 line
2.14.2
#23 lore raw

PATCH 8/67 powerpc: remove unused flush_write_buffers definition

In reply to Christoph Hellwig
---
 arch/powerpc/include/asm/dma-mapping.h | 3 ---
 1 file changed, 3 deletions(-)
arch/powerpc/include/asm/dma-mapping.h +0 -3
index 5a6cbe11db6f..592c7f418aa0 100644
@@ -107,9 +107,6 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
 		dev->archdata.dma_offset = off;
 }
 
-/* this will be removed soon */
-#define flush_write_buffers()
-
 #define HAVE_ARCH_DMA_SET_MASK 1
 extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
Signature · 1 line
2.14.2
#24 lore raw

PATCH 9/67 arc: remove CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA

In reply to Christoph Hellwig

We always use the stub definitions, so remove the unused other code.

---
 arch/arc/Kconfig                   |  3 ---
 arch/arc/include/asm/dma-mapping.h |  7 -------
 arch/arc/mm/dma.c                  | 14 +++++++-------
 3 files changed, 7 insertions(+), 17 deletions(-)
arch/arc/Kconfig +0 -3
index 9d5fd00d9e91..f3a80cf164cc 100644
@@ -463,9 +463,6 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
 	bool
 
-config ARC_PLAT_NEEDS_PHYS_TO_DMA
-	bool
-
 config ARC_KVADDR_SIZE
 	int "Kernel Virtual Address Space size (MB)"
 	range 0 512
arch/arc/include/asm/dma-mapping.h +0 -7
index 94285031c4fb..7a16824bfe98 100644
@@ -11,13 +11,6 @@
 #ifndef ASM_ARC_DMA_MAPPING_H
 #define ASM_ARC_DMA_MAPPING_H
 
-#ifndef CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA
-#define plat_dma_to_phys(dev, dma_handle) ((phys_addr_t)(dma_handle))
-#define plat_phys_to_dma(dev, paddr) ((dma_addr_t)(paddr))
-#else
-#include <plat/dma.h>
-#endif
-
 extern const struct dma_map_ops arc_dma_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
arch/arc/mm/dma.c +7 -7
index fad18261ef6a..1d405b86250c 100644
@@ -60,7 +60,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
 	/* This is linear addr (0x8000_0000 based) */
 	paddr = page_to_phys(page);
 
-	*dma_handle = plat_phys_to_dma(dev, paddr);
+	*dma_handle = paddr;
 
 	/* This is kernel Virtual address (0x7000_0000 based) */
 	if (need_kvaddr) {
@@ -92,7 +92,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
 static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
 		dma_addr_t dma_handle, unsigned long attrs)
 {
-	phys_addr_t paddr = plat_dma_to_phys(dev, dma_handle);
+	phys_addr_t paddr = dma_handle;
 	struct page *page = virt_to_page(paddr);
 	int is_non_coh = 1;
 
@@ -111,7 +111,7 @@ static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 {
 	unsigned long user_count = vma_pages(vma);
 	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
-	unsigned long pfn = __phys_to_pfn(plat_dma_to_phys(dev, dma_addr));
+	unsigned long pfn = __phys_to_pfn(dma_addr);
 	unsigned long off = vma->vm_pgoff;
 	int ret = -ENXIO;
 
@@ -175,7 +175,7 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
 	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
 		_dma_cache_sync(paddr, size, dir);
 
-	return plat_phys_to_dma(dev, paddr);
+	return paddr;
 }
 
 /*
@@ -190,7 +190,7 @@ static void arc_dma_unmap_page(struct device *dev, dma_addr_t handle,
 			       size_t size, enum dma_data_direction dir,
 			       unsigned long attrs)
 {
-	phys_addr_t paddr = plat_dma_to_phys(dev, handle);
+	phys_addr_t paddr = handle;
 
 	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
 		_dma_cache_sync(paddr, size, dir);
@@ -224,13 +224,13 @@ static void arc_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 static void arc_dma_sync_single_for_cpu(struct device *dev,
 		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
 {
-	_dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_FROM_DEVICE);
+	_dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE);
 }
 
 static void arc_dma_sync_single_for_device(struct device *dev,
 		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
 {
-	_dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_TO_DEVICE);
+	_dma_cache_sync(dma_handle, size, DMA_TO_DEVICE);
 }
 
 static void arc_dma_sync_sg_for_cpu(struct device *dev,
Signature · 1 line
2.14.2
Acked-by on v1 9/67
#25 lore raw

Re: [PATCH 09/67] arc: remove CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA

Quoted 3 lines · Christoph Hellwig

We always use the stub definitions, so remove the unused other code.

FWIW, it was removed and reintroduced as one of the customers wanted it, which is not relevant now !

Thx,
-Vineet

Quoted 103 lines
---
  arch/arc/Kconfig                   |  3 ---
  arch/arc/include/asm/dma-mapping.h |  7 -------
  arch/arc/mm/dma.c                  | 14 +++++++-------
  3 files changed, 7 insertions(+), 17 deletions(-)
arch/arc/Kconfig +0 -3
index 9d5fd00d9e91..f3a80cf164cc 100644
@@ -463,9 +463,6 @@ config ARCH_PHYS_ADDR_T_64BIT
  config ARCH_DMA_ADDR_T_64BIT
  	bool
 
-config ARC_PLAT_NEEDS_PHYS_TO_DMA
-	bool
-
  config ARC_KVADDR_SIZE
  	int "Kernel Virtual Address Space size (MB)"
  	range 0 512
arch/arc/include/asm/dma-mapping.h +0 -7
index 94285031c4fb..7a16824bfe98 100644
@@ -11,13 +11,6 @@
  #ifndef ASM_ARC_DMA_MAPPING_H
  #define ASM_ARC_DMA_MAPPING_H
 
-#ifndef CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA
-#define plat_dma_to_phys(dev, dma_handle) ((phys_addr_t)(dma_handle))
-#define plat_phys_to_dma(dev, paddr) ((dma_addr_t)(paddr))
-#else
-#include <plat/dma.h>
-#endif
-
  extern const struct dma_map_ops arc_dma_ops;
 
  static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
arch/arc/mm/dma.c +7 -7
index fad18261ef6a..1d405b86250c 100644
@@ -60,7 +60,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
  	/* This is linear addr (0x8000_0000 based) */
  	paddr = page_to_phys(page);
 
-	*dma_handle = plat_phys_to_dma(dev, paddr);
+	*dma_handle = paddr;
 
  	/* This is kernel Virtual address (0x7000_0000 based) */
  	if (need_kvaddr) {
@@ -92,7 +92,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
  static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
  		dma_addr_t dma_handle, unsigned long attrs)
  {
-	phys_addr_t paddr = plat_dma_to_phys(dev, dma_handle);
+	phys_addr_t paddr = dma_handle;
  	struct page *page = virt_to_page(paddr);
  	int is_non_coh = 1;
 
@@ -111,7 +111,7 @@ static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  {
  	unsigned long user_count = vma_pages(vma);
  	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
-	unsigned long pfn = __phys_to_pfn(plat_dma_to_phys(dev, dma_addr));
+	unsigned long pfn = __phys_to_pfn(dma_addr);
  	unsigned long off = vma->vm_pgoff;
  	int ret = -ENXIO;
 
@@ -175,7 +175,7 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
  	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
  		_dma_cache_sync(paddr, size, dir);
 
-	return plat_phys_to_dma(dev, paddr);
+	return paddr;
  }
 
  /*
@@ -190,7 +190,7 @@ static void arc_dma_unmap_page(struct device *dev, dma_addr_t handle,
  			       size_t size, enum dma_data_direction dir,
  			       unsigned long attrs)
  {
-	phys_addr_t paddr = plat_dma_to_phys(dev, handle);
+	phys_addr_t paddr = handle;
 
  	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
  		_dma_cache_sync(paddr, size, dir);
@@ -224,13 +224,13 @@ static void arc_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
  static void arc_dma_sync_single_for_cpu(struct device *dev,
  		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
  {
-	_dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_FROM_DEVICE);
+	_dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE);
  }
 
  static void arc_dma_sync_single_for_device(struct device *dev,
  		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
  {
-	_dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_TO_DEVICE);
+	_dma_cache_sync(dma_handle, size, DMA_TO_DEVICE);
  }
 
  static void arc_dma_sync_sg_for_cpu(struct device *dev,
Acked-by on v1 9/67
#26 lore raw

Re: [PATCH 09/67] arc: remove CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA

In reply to Christoph Hellwig
Quoted 3 lines · Christoph Hellwig

We always use the stub definitions, so remove the unused other code.

FWIW, it was removed and reintroduced as one of the customers wanted it, which is not relevant now !

Thx,
-Vineet

Quoted 103 lines
---
  arch/arc/Kconfig                   |  3 ---
  arch/arc/include/asm/dma-mapping.h |  7 -------
  arch/arc/mm/dma.c                  | 14 +++++++-------
  3 files changed, 7 insertions(+), 17 deletions(-)
arch/arc/Kconfig +0 -3
index 9d5fd00d9e91..f3a80cf164cc 100644
@@ -463,9 +463,6 @@ config ARCH_PHYS_ADDR_T_64BIT
  config ARCH_DMA_ADDR_T_64BIT
  	bool
 
-config ARC_PLAT_NEEDS_PHYS_TO_DMA
-	bool
-
  config ARC_KVADDR_SIZE
  	int "Kernel Virtual Address Space size (MB)"
  	range 0 512
arch/arc/include/asm/dma-mapping.h +0 -7
index 94285031c4fb..7a16824bfe98 100644
@@ -11,13 +11,6 @@
  #ifndef ASM_ARC_DMA_MAPPING_H
  #define ASM_ARC_DMA_MAPPING_H
 
-#ifndef CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA
-#define plat_dma_to_phys(dev, dma_handle) ((phys_addr_t)(dma_handle))
-#define plat_phys_to_dma(dev, paddr) ((dma_addr_t)(paddr))
-#else
-#include <plat/dma.h>
-#endif
-
  extern const struct dma_map_ops arc_dma_ops;
 
  static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
arch/arc/mm/dma.c +7 -7
index fad18261ef6a..1d405b86250c 100644
@@ -60,7 +60,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
  	/* This is linear addr (0x8000_0000 based) */
  	paddr = page_to_phys(page);
 
-	*dma_handle = plat_phys_to_dma(dev, paddr);
+	*dma_handle = paddr;
 
  	/* This is kernel Virtual address (0x7000_0000 based) */
  	if (need_kvaddr) {
@@ -92,7 +92,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
  static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
  		dma_addr_t dma_handle, unsigned long attrs)
  {
-	phys_addr_t paddr = plat_dma_to_phys(dev, dma_handle);
+	phys_addr_t paddr = dma_handle;
  	struct page *page = virt_to_page(paddr);
  	int is_non_coh = 1;
 
@@ -111,7 +111,7 @@ static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,
  {
  	unsigned long user_count = vma_pages(vma);
  	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
-	unsigned long pfn = __phys_to_pfn(plat_dma_to_phys(dev, dma_addr));
+	unsigned long pfn = __phys_to_pfn(dma_addr);
  	unsigned long off = vma->vm_pgoff;
  	int ret = -ENXIO;
 
@@ -175,7 +175,7 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
  	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
  		_dma_cache_sync(paddr, size, dir);
 
-	return plat_phys_to_dma(dev, paddr);
+	return paddr;
  }
 
  /*
@@ -190,7 +190,7 @@ static void arc_dma_unmap_page(struct device *dev, dma_addr_t handle,
  			       size_t size, enum dma_data_direction dir,
  			       unsigned long attrs)
  {
-	phys_addr_t paddr = plat_dma_to_phys(dev, handle);
+	phys_addr_t paddr = handle;
 
  	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
  		_dma_cache_sync(paddr, size, dir);
@@ -224,13 +224,13 @@ static void arc_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
  static void arc_dma_sync_single_for_cpu(struct device *dev,
  		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
  {
-	_dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_FROM_DEVICE);
+	_dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE);
  }
 
  static void arc_dma_sync_single_for_device(struct device *dev,
  		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
  {
-	_dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_TO_DEVICE);
+	_dma_cache_sync(dma_handle, size, DMA_TO_DEVICE);
  }
 
  static void arc_dma_sync_sg_for_cpu(struct device *dev,
#27 lore raw

PATCH 9/67 arc: remove CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA

In reply to Christoph Hellwig

We always use the stub definitions, so remove the unused other code.

---
 arch/arc/Kconfig                   |  3 ---
 arch/arc/include/asm/dma-mapping.h |  7 -------
 arch/arc/mm/dma.c                  | 14 +++++++-------
 3 files changed, 7 insertions(+), 17 deletions(-)
arch/arc/Kconfig +0 -3
index 9d5fd00d9e91..f3a80cf164cc 100644
@@ -463,9 +463,6 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
 	bool
 
-config ARC_PLAT_NEEDS_PHYS_TO_DMA
-	bool
-
 config ARC_KVADDR_SIZE
 	int "Kernel Virtual Address Space size (MB)"
 	range 0 512
arch/arc/include/asm/dma-mapping.h +0 -7
index 94285031c4fb..7a16824bfe98 100644
@@ -11,13 +11,6 @@
 #ifndef ASM_ARC_DMA_MAPPING_H
 #define ASM_ARC_DMA_MAPPING_H
 
-#ifndef CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA
-#define plat_dma_to_phys(dev, dma_handle) ((phys_addr_t)(dma_handle))
-#define plat_phys_to_dma(dev, paddr) ((dma_addr_t)(paddr))
-#else
-#include <plat/dma.h>
-#endif
-
 extern const struct dma_map_ops arc_dma_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
arch/arc/mm/dma.c +7 -7
index fad18261ef6a..1d405b86250c 100644
@@ -60,7 +60,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
 	/* This is linear addr (0x8000_0000 based) */
 	paddr = page_to_phys(page);
 
-	*dma_handle = plat_phys_to_dma(dev, paddr);
+	*dma_handle = paddr;
 
 	/* This is kernel Virtual address (0x7000_0000 based) */
 	if (need_kvaddr) {
@@ -92,7 +92,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
 static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
 		dma_addr_t dma_handle, unsigned long attrs)
 {
-	phys_addr_t paddr = plat_dma_to_phys(dev, dma_handle);
+	phys_addr_t paddr = dma_handle;
 	struct page *page = virt_to_page(paddr);
 	int is_non_coh = 1;
 
@@ -111,7 +111,7 @@ static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 {
 	unsigned long user_count = vma_pages(vma);
 	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
-	unsigned long pfn = __phys_to_pfn(plat_dma_to_phys(dev, dma_addr));
+	unsigned long pfn = __phys_to_pfn(dma_addr);
 	unsigned long off = vma->vm_pgoff;
 	int ret = -ENXIO;
 
@@ -175,7 +175,7 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
 	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
 		_dma_cache_sync(paddr, size, dir);
 
-	return plat_phys_to_dma(dev, paddr);
+	return paddr;
 }
 
 /*
@@ -190,7 +190,7 @@ static void arc_dma_unmap_page(struct device *dev, dma_addr_t handle,
 			       size_t size, enum dma_data_direction dir,
 			       unsigned long attrs)
 {
-	phys_addr_t paddr = plat_dma_to_phys(dev, handle);
+	phys_addr_t paddr = handle;
 
 	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
 		_dma_cache_sync(paddr, size, dir);
@@ -224,13 +224,13 @@ static void arc_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 static void arc_dma_sync_single_for_cpu(struct device *dev,
 		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
 {
-	_dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_FROM_DEVICE);
+	_dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE);
 }
 
 static void arc_dma_sync_single_for_device(struct device *dev,
 		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
 {
-	_dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_TO_DEVICE);
+	_dma_cache_sync(dma_handle, size, DMA_TO_DEVICE);
 }
 
 static void arc_dma_sync_sg_for_cpu(struct device *dev,
Signature · 1 line
2.14.2
#28 lore raw

PATCH 10/67 m32r: remove the unused dma_capable helper

In reply to Christoph Hellwig
---
 arch/m32r/include/asm/dma-mapping.h | 7 -------
 1 file changed, 7 deletions(-)
arch/m32r/include/asm/dma-mapping.h +0 -7
index 336ffe60814b..8967fb659691 100644
@@ -14,11 +14,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &dma_noop_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #endif /* _ASM_M32R_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#29 lore raw

PATCH 10/67 m32r: remove the unused dma_capable helper

In reply to Christoph Hellwig
---
 arch/m32r/include/asm/dma-mapping.h | 7 -------
 1 file changed, 7 deletions(-)
arch/m32r/include/asm/dma-mapping.h +0 -7
index 336ffe60814b..8967fb659691 100644
@@ -14,11 +14,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &dma_noop_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #endif /* _ASM_M32R_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#30 lore raw

PATCH 11/67 riscv: remove the unused dma_capable helper

In reply to Christoph Hellwig
---
 arch/riscv/include/asm/dma-mapping.h | 8 --------
 1 file changed, 8 deletions(-)
arch/riscv/include/asm/dma-mapping.h +0 -8
index 3eec1000196d..73849e2cc761 100644
@@ -27,12 +27,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &dma_noop_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #endif	/* __ASM_RISCV_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#31 lore raw

PATCH 11/67 riscv: remove the unused dma_capable helper

In reply to Christoph Hellwig
---
 arch/riscv/include/asm/dma-mapping.h | 8 --------
 1 file changed, 8 deletions(-)
arch/riscv/include/asm/dma-mapping.h +0 -8
index 3eec1000196d..73849e2cc761 100644
@@ -27,12 +27,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &dma_noop_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #endif	/* __ASM_RISCV_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#32 lore raw

PATCH 12/67 s390: remove the unused dma_capable helper

In reply to Christoph Hellwig
---
 arch/s390/include/asm/dma-mapping.h | 7 -------
 1 file changed, 7 deletions(-)
arch/s390/include/asm/dma-mapping.h +0 -7
index eaf490f9c5bc..2ec7240c1ada 100644
@@ -16,11 +16,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &dma_noop_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #endif /* _ASM_S390_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#33 lore raw

PATCH 12/67 s390: remove the unused dma_capable helper

In reply to Christoph Hellwig
---
 arch/s390/include/asm/dma-mapping.h | 7 -------
 1 file changed, 7 deletions(-)
arch/s390/include/asm/dma-mapping.h +0 -7
index eaf490f9c5bc..2ec7240c1ada 100644
@@ -16,11 +16,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &dma_noop_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #endif /* _ASM_S390_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#34 lore raw

PATCH 13/67 dma-mapping: move swiotlb arch helpers to a new header

In reply to Christoph Hellwig

phys_to_dma, dma_to_phys and dma_capable are helpers published by architecture code for use of swiotlb and xen-swiotlb only. Drivers are not supposed to use these directly, but use the DMA API instead.

Move these to a new asm/dma-direct.h helper, included by a linux/dma-direct.h wrapper that provides the default linear mapping unless the architecture wants to override it.

---
 MAINTAINERS                                        |  1 +
 arch/Kconfig                                       |  4 +++
 arch/arm/Kconfig                                   |  1 +
 arch/arm/include/asm/dma-direct.h                  | 36 ++++++++++++++++++++++
 arch/arm/include/asm/dma-mapping.h                 | 31 -------------------
 arch/arm64/include/asm/dma-mapping.h               | 22 -------------
 arch/arm64/mm/dma-mapping.c                        |  2 +-
 arch/ia64/include/asm/dma-mapping.h                | 18 -----------
 arch/mips/Kconfig                                  |  2 ++
 arch/mips/include/asm/dma-direct.h                 |  1 +
 arch/mips/include/asm/dma-mapping.h                |  8 -----
 .../include/asm/mach-cavium-octeon/dma-coherence.h |  8 +++++
 arch/mips/include/asm/mach-generic/dma-coherence.h | 12 --------
 .../include/asm/mach-loongson64/dma-coherence.h    |  8 +++++
 arch/powerpc/Kconfig                               |  1 +
 arch/powerpc/include/asm/dma-direct.h              | 29 +++++++++++++++++
 arch/powerpc/include/asm/dma-mapping.h             | 25 ---------------
 arch/tile/include/asm/dma-mapping.h                | 18 -----------
 arch/unicore32/include/asm/dma-mapping.h           | 18 -----------
 arch/x86/Kconfig                                   |  1 +
 arch/x86/include/asm/dma-direct.h                  | 30 ++++++++++++++++++
 arch/x86/include/asm/dma-mapping.h                 | 26 ----------------
 arch/x86/kernel/amd_gart_64.c                      |  1 +
 arch/x86/kernel/pci-dma.c                          |  2 +-
 arch/x86/kernel/pci-nommu.c                        |  2 +-
 arch/x86/kernel/pci-swiotlb.c                      |  2 +-
 arch/x86/mm/mem_encrypt.c                          |  2 +-
 arch/x86/pci/sta2x11-fixup.c                       |  1 +
 arch/xtensa/include/asm/dma-mapping.h              | 10 ------
 drivers/crypto/marvell/cesa.c                      |  1 +
 drivers/mtd/nand/qcom_nandc.c                      |  1 +
 drivers/xen/swiotlb-xen.c                          |  2 +-
 include/linux/dma-direct.h                         | 32 +++++++++++++++++++
 lib/swiotlb.c                                      |  2 +-
 34 files changed, 165 insertions(+), 195 deletions(-)
 create mode 100644 arch/arm/include/asm/dma-direct.h
 create mode 100644 arch/mips/include/asm/dma-direct.h
 create mode 100644 arch/powerpc/include/asm/dma-direct.h
 create mode 100644 arch/x86/include/asm/dma-direct.h
 create mode 100644 include/linux/dma-direct.h
MAINTAINERS +1 -0
index a6e86e20761e..7521b063b499 100644
@@ -4340,6 +4340,7 @@ F:	lib/dma-noop.c
 F:	lib/dma-virt.c
 F:	drivers/base/dma-mapping.c
 F:	drivers/base/dma-coherent.c
+F:	include/linux/dma-direct.h
 F:	include/linux/dma-mapping.h
 
 DME1737 HARDWARE MONITOR DRIVER
arch/Kconfig +4 -0
index 400b9e1b2f27..3edf118ad777 100644
@@ -938,6 +938,10 @@ config STRICT_MODULE_RWX
 	  and non-text memory will be made non-executable. This provides
 	  protection against certain security exploits (e.g. writing to text)
 
+# select if the architecture provides an asm/dma-direct.h header
+config ARCH_HAS_PHYS_TO_DMA
+	bool
+
 config ARCH_HAS_REFCOUNT
 	bool
 	help
arch/arm/Kconfig +1 -0
index 51c8df561077..00d889a37965 100644
@@ -8,6 +8,7 @@ config ARM
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_SET_MEMORY
+	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL
 	select ARCH_HAS_STRICT_MODULE_RWX if MMU
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
arch/arm/include/asm/dma-direct.h new file +36 -0
new file mode 100644
index 000000000000..5b0a8a421894
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ASM_ARM_DMA_DIRECT_H
+#define ASM_ARM_DMA_DIRECT_H 1
+
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	unsigned int offset = paddr & ~PAGE_MASK;
+	return pfn_to_dma(dev, __phys_to_pfn(paddr)) + offset;
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
+{
+	unsigned int offset = dev_addr & ~PAGE_MASK;
+	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
+}
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	u64 limit, mask;
+
+	if (!dev->dma_mask)
+		return 0;
+
+	mask = *dev->dma_mask;
+
+	limit = (mask + 1) & ~mask;
+	if (limit && size > limit)
+		return 0;
+
+	if ((addr | (addr + size - 1)) & ~mask)
+		return 0;
+
+	return 1;
+}
+
+#endif /* ASM_ARM_DMA_DIRECT_H */
arch/arm/include/asm/dma-mapping.h +0 -31
index daf837423a76..5fb1b7fbdfbe 100644
@@ -109,37 +109,6 @@ static inline bool is_device_dma_coherent(struct device *dev)
 	return dev->archdata.dma_coherent;
 }
 
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	unsigned int offset = paddr & ~PAGE_MASK;
-	return pfn_to_dma(dev, __phys_to_pfn(paddr)) + offset;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
-{
-	unsigned int offset = dev_addr & ~PAGE_MASK;
-	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
-}
-
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	u64 limit, mask;
-
-	if (!dev->dma_mask)
-		return 0;
-
-	mask = *dev->dma_mask;
-
-	limit = (mask + 1) & ~mask;
-	if (limit && size > limit)
-		return 0;
-
-	if ((addr | (addr + size - 1)) & ~mask)
-		return 0;
-
-	return 1;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size) { }
 
 /**
arch/arm64/include/asm/dma-mapping.h +0 -22
index eada887a93bf..400fa67d3b5a 100644
@@ -50,28 +50,6 @@ static inline bool is_device_dma_coherent(struct device *dev)
 	return dev->archdata.dma_coherent;
 }
 
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	dma_addr_t dev_addr = (dma_addr_t)paddr;
-
-	return dev_addr - ((dma_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
-{
-	phys_addr_t paddr = (phys_addr_t)dev_addr;
-
-	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
-}
-
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size)
 {
 }
arch/arm64/mm/dma-mapping.c +1 -1
index b45c5bcaeccb..f3a637b98487 100644
@@ -24,7 +24,7 @@
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/genalloc.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/dma-contiguous.h>
 #include <linux/vmalloc.h>
 #include <linux/swiotlb.h>
arch/ia64/include/asm/dma-mapping.h +0 -18
index c1bab526a046..eabee56d995c 100644
@@ -27,22 +27,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return platform_dma_get_ops(NULL);
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return 0;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr;
-}
-
 #endif /* _ASM_IA64_DMA_MAPPING_H */
arch/mips/Kconfig +2 -0
index 350a990fc719..4b0c26b2e9b7 100644
@@ -429,6 +429,7 @@ config MACH_LOONGSON32
 
 config MACH_LOONGSON64
 	bool "Loongson-2/3 family of machines"
+	select ARCH_HAS_PHYS_TO_DMA
 	select SYS_SUPPORTS_ZBOOT
 	help
 	  This enables the support of Loongson-2/3 family of machines.
@@ -877,6 +878,7 @@ config MIKROTIK_RB532
 config CAVIUM_OCTEON_SOC
 	bool "Cavium Networks Octeon SoC based boards"
 	select CEVT_R4K
+	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_PHYS_ADDR_T_64BIT
 	select DMA_COHERENT
 	select SYS_SUPPORTS_64BIT_KERNEL
arch/mips/include/asm/dma-direct.h new file +1 -0
new file mode 100644
index 000000000000..f32f15530aba
@@ -0,0 +1 @@
+#include <asm/dma-coherence.h>
arch/mips/include/asm/dma-mapping.h +0 -8
index 0d9418d264f9..676c14cfc580 100644
@@ -17,14 +17,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return mips_dma_map_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size <= *dev->dma_mask;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
 #define arch_setup_dma_ops arch_setup_dma_ops
arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h +8 -0
index 9110988b92a1..f00833acb626 100644
@@ -61,6 +61,14 @@ static inline void plat_post_dma_flush(struct device *dev)
 {
 }
 
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (!dev->dma_mask)
+		return false;
+
+	return addr + size <= *dev->dma_mask;
+}
+
 dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
 phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
 
arch/mips/include/asm/mach-generic/dma-coherence.h +0 -12
index 61addb1677e9..8ad7a40ca786 100644
@@ -70,16 +70,4 @@ static inline void plat_post_dma_flush(struct device *dev)
 }
 #endif
 
-#ifdef CONFIG_SWIOTLB
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr;
-}
-#endif
-
 #endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */
arch/mips/include/asm/mach-loongson64/dma-coherence.h +8 -0
index 1602a9e9e8c2..5cfda8f893e9 100644
@@ -17,6 +17,14 @@
 
 struct device;
 
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (!dev->dma_mask)
+		return false;
+
+	return addr + size <= *dev->dma_mask;
+}
+
 extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
 extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
 static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
arch/powerpc/Kconfig +1 -0
index c51e6ce42e7a..887285eb684a 100644
@@ -139,6 +139,7 @@ config PPC
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_HAS_PMEM_API                if PPC64
 	select ARCH_HAS_SCALED_CPUTIME		if VIRT_CPU_ACCOUNTING_NATIVE
 	select ARCH_HAS_SG_CHAIN
arch/powerpc/include/asm/dma-direct.h new file +29 -0
new file mode 100644
index 000000000000..a5b59c765426
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ASM_POWERPC_DMA_DIRECT_H
+#define ASM_POWERPC_DMA_DIRECT_H 1
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+#ifdef CONFIG_SWIOTLB
+	struct dev_archdata *sd = &dev->archdata;
+
+	if (sd->max_direct_dma_addr && addr + size > sd->max_direct_dma_addr)
+		return false;
+#endif
+
+	if (!dev->dma_mask)
+		return false;
+
+	return addr + size - 1 <= *dev->dma_mask;
+}
+
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	return paddr + get_dma_offset(dev);
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+	return daddr - get_dma_offset(dev);
+}
+#endif /* ASM_POWERPC_DMA_DIRECT_H */
arch/powerpc/include/asm/dma-mapping.h +0 -25
index 592c7f418aa0..f6ab51205a85 100644
@@ -112,31 +112,6 @@ extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
 extern u64 __dma_get_required_mask(struct device *dev);
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-#ifdef CONFIG_SWIOTLB
-	struct dev_archdata *sd = &dev->archdata;
-
-	if (sd->max_direct_dma_addr && addr + size > sd->max_direct_dma_addr)
-		return false;
-#endif
-
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr + get_dma_offset(dev);
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr - get_dma_offset(dev);
-}
-
 #define ARCH_HAS_DMA_MMAP_COHERENT
 
 #endif /* __KERNEL__ */
arch/tile/include/asm/dma-mapping.h +0 -18
index 97ad62878290..75b8aaa4e70b 100644
@@ -44,26 +44,8 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
 	dev->archdata.dma_offset = off;
 }
 
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return 0;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #define HAVE_ARCH_DMA_SET_MASK 1
 int dma_set_mask(struct device *dev, u64 mask);
 
arch/unicore32/include/asm/dma-mapping.h +0 -18
index ac608c2f6af6..5cb250bf2d8c 100644
@@ -25,24 +25,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &swiotlb_dma_map_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (dev && dev->dma_mask)
-		return addr + size - 1 <= *dev->dma_mask;
-
-	return 1;
-}
-
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
 #endif /* __KERNEL__ */
arch/x86/Kconfig +1 -0
index d4fc98c50378..f6f4328103c0 100644
@@ -54,6 +54,7 @@ config X86
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV			if X86_64
+	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_HAS_PMEM_API		if X86_64
 	# Causing hangs/crashes, see the commit that added this change for details.
 	select ARCH_HAS_REFCOUNT
arch/x86/include/asm/dma-direct.h new file +30 -0
new file mode 100644
index 000000000000..1295bc622ebe
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ASM_X86_DMA_DIRECT_H
+#define ASM_X86_DMA_DIRECT_H 1
+
+#include <linux/mem_encrypt.h>
+
+#ifdef CONFIG_X86_DMA_REMAP /* Platform code defines bridge-specific code */
+bool dma_capable(struct device *dev, dma_addr_t addr, size_t size);
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
+#else
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (!dev->dma_mask)
+		return 0;
+
+	return addr + size - 1 <= *dev->dma_mask;
+}
+
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	return __sme_set(paddr);
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+	return __sme_clr(daddr);
+}
+#endif /* CONFIG_X86_DMA_REMAP */
+#endif /* ASM_X86_DMA_DIRECT_H */
arch/x86/include/asm/dma-mapping.h +0 -26
index 0350d99bb8fd..dfdc9357a349 100644
@@ -12,7 +12,6 @@
 #include <asm/io.h>
 #include <asm/swiotlb.h>
 #include <linux/dma-contiguous.h>
-#include <linux/mem_encrypt.h>
 
 #ifdef CONFIG_ISA
 # define ISA_DMA_BIT_MASK DMA_BIT_MASK(24)
@@ -42,31 +41,6 @@ extern void dma_generic_free_coherent(struct device *dev, size_t size,
 				      void *vaddr, dma_addr_t dma_addr,
 				      unsigned long attrs);
 
-#ifdef CONFIG_X86_DMA_REMAP /* Platform code defines bridge-specific code */
-extern bool dma_capable(struct device *dev, dma_addr_t addr, size_t size);
-extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
-extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
-#else
-
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return 0;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return __sme_set(paddr);
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return __sme_clr(daddr);
-}
-#endif /* CONFIG_X86_DMA_REMAP */
-
 static inline unsigned long dma_alloc_coherent_mask(struct device *dev,
 						    gfp_t gfp)
 {
arch/x86/kernel/amd_gart_64.c +1 -0
index cc0e8bc0ea3f..ecd486cb06ab 100644
@@ -31,6 +31,7 @@
 #include <linux/io.h>
 #include <linux/gfp.h>
 #include <linux/atomic.h>
+#include <linux/dma-direct.h>
 #include <asm/mtrr.h>
 #include <asm/pgtable.h>
 #include <asm/proto.h>
arch/x86/kernel/pci-dma.c +1 -1
index 599d7462eccc..8439e6de6156 100644
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/dma-debug.h>
 #include <linux/dmar.h>
 #include <linux/export.h>
arch/x86/kernel/pci-nommu.c +1 -1
index 8ac9d1fe0373..8b8ff98486de 100644
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Fallback functions when the main IOMMU code is not compiled in. This
    code is roughly equivalent to i386. */
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
 #include <linux/string.h>
 #include <linux/gfp.h>
arch/x86/kernel/pci-swiotlb.c +1 -1
index 53bd05ea90d8..9d3e35c33d94 100644
@@ -6,7 +6,7 @@
 #include <linux/init.h>
 #include <linux/swiotlb.h>
 #include <linux/bootmem.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/mem_encrypt.h>
 
 #include <asm/iommu.h>
arch/x86/mm/mem_encrypt.c +1 -1
index d9a9e9fc75dd..764b916ef7da 100644
@@ -15,7 +15,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/mm.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/swiotlb.h>
 #include <linux/mem_encrypt.h>
 
arch/x86/pci/sta2x11-fixup.c +1 -0
index 53d600217973..75577c1490c4 100644
@@ -26,6 +26,7 @@
 #include <linux/pci_ids.h>
 #include <linux/export.h>
 #include <linux/list.h>
+#include <linux/dma-direct.h>
 #include <asm/iommu.h>
 
 #define STA2X11_SWIOTLB_SIZE (4*1024*1024)
arch/xtensa/include/asm/dma-mapping.h +0 -10
index 153bf2370988..44098800dad7 100644
@@ -23,14 +23,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &xtensa_dma_map_ops;
 }
 
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return (dma_addr_t)paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return (phys_addr_t)daddr;
-}
-
 #endif	/* _XTENSA_DMA_MAPPING_H */
drivers/crypto/marvell/cesa.c +1 -0
index 293832488cc9..3a0c40081ffb 100644
@@ -24,6 +24,7 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/dma-direct.h> /* XXX: drivers shall never use this directly! */
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
drivers/mtd/nand/qcom_nandc.c +1 -0
index 2656c1ac5646..411cdfd12a85 100644
@@ -23,6 +23,7 @@
 #include <linux/of_device.h>
 #include <linux/delay.h>
 #include <linux/dma/qcom_bam_dma.h>
+#include <linux/dma-direct.h> /* XXX: drivers shall never use this directly! */
 
 /* NANDc reg offsets */
 #define	NAND_FLASH_CMD			0x00
drivers/xen/swiotlb-xen.c +1 -1
index 82fc54f8eb77..5bb72d3f8337 100644
@@ -36,7 +36,7 @@
 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
 
 #include <linux/bootmem.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/export.h>
 #include <xen/swiotlb-xen.h>
 #include <xen/page.h>
include/linux/dma-direct.h new file +32 -0
new file mode 100644
index 000000000000..2cc1b6558944
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_DMA_DIRECT_H
+#define _LINUX_DMA_DIRECT_H 1
+
+#include <linux/dma-mapping.h>
+
+#ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
+#include <asm/dma-direct.h>
+#else
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	dma_addr_t dev_addr = (dma_addr_t)paddr;
+
+	return dev_addr - ((dma_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
+{
+	phys_addr_t paddr = (phys_addr_t)dev_addr;
+
+	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
+}
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (!dev->dma_mask)
+		return false;
+
+	return addr + size - 1 <= *dev->dma_mask;
+}
+#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
+#endif /* _LINUX_DMA_DIRECT_H */
lib/swiotlb.c +1 -1
index cea19aaf303c..6583f3512386 100644
@@ -18,7 +18,7 @@
  */
 
 #include <linux/cache.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/mm.h>
 #include <linux/export.h>
 #include <linux/spinlock.h>
Signature · 1 line
2.14.2
#35 lore raw

PATCH 13/67 dma-mapping: move swiotlb arch helpers to a new header

In reply to Christoph Hellwig

phys_to_dma, dma_to_phys and dma_capable are helpers published by architecture code for use of swiotlb and xen-swiotlb only. Drivers are not supposed to use these directly, but use the DMA API instead.

Move these to a new asm/dma-direct.h helper, included by a linux/dma-direct.h wrapper that provides the default linear mapping unless the architecture wants to override it.

---
 MAINTAINERS                                        |  1 +
 arch/Kconfig                                       |  4 +++
 arch/arm/Kconfig                                   |  1 +
 arch/arm/include/asm/dma-direct.h                  | 36 ++++++++++++++++++++++
 arch/arm/include/asm/dma-mapping.h                 | 31 -------------------
 arch/arm64/include/asm/dma-mapping.h               | 22 -------------
 arch/arm64/mm/dma-mapping.c                        |  2 +-
 arch/ia64/include/asm/dma-mapping.h                | 18 -----------
 arch/mips/Kconfig                                  |  2 ++
 arch/mips/include/asm/dma-direct.h                 |  1 +
 arch/mips/include/asm/dma-mapping.h                |  8 -----
 .../include/asm/mach-cavium-octeon/dma-coherence.h |  8 +++++
 arch/mips/include/asm/mach-generic/dma-coherence.h | 12 --------
 .../include/asm/mach-loongson64/dma-coherence.h    |  8 +++++
 arch/powerpc/Kconfig                               |  1 +
 arch/powerpc/include/asm/dma-direct.h              | 29 +++++++++++++++++
 arch/powerpc/include/asm/dma-mapping.h             | 25 ---------------
 arch/tile/include/asm/dma-mapping.h                | 18 -----------
 arch/unicore32/include/asm/dma-mapping.h           | 18 -----------
 arch/x86/Kconfig                                   |  1 +
 arch/x86/include/asm/dma-direct.h                  | 30 ++++++++++++++++++
 arch/x86/include/asm/dma-mapping.h                 | 26 ----------------
 arch/x86/kernel/amd_gart_64.c                      |  1 +
 arch/x86/kernel/pci-dma.c                          |  2 +-
 arch/x86/kernel/pci-nommu.c                        |  2 +-
 arch/x86/kernel/pci-swiotlb.c                      |  2 +-
 arch/x86/mm/mem_encrypt.c                          |  2 +-
 arch/x86/pci/sta2x11-fixup.c                       |  1 +
 arch/xtensa/include/asm/dma-mapping.h              | 10 ------
 drivers/crypto/marvell/cesa.c                      |  1 +
 drivers/mtd/nand/qcom_nandc.c                      |  1 +
 drivers/xen/swiotlb-xen.c                          |  2 +-
 include/linux/dma-direct.h                         | 32 +++++++++++++++++++
 lib/swiotlb.c                                      |  2 +-
 34 files changed, 165 insertions(+), 195 deletions(-)
 create mode 100644 arch/arm/include/asm/dma-direct.h
 create mode 100644 arch/mips/include/asm/dma-direct.h
 create mode 100644 arch/powerpc/include/asm/dma-direct.h
 create mode 100644 arch/x86/include/asm/dma-direct.h
 create mode 100644 include/linux/dma-direct.h
MAINTAINERS +1 -0
index a6e86e20761e..7521b063b499 100644
@@ -4340,6 +4340,7 @@ F:	lib/dma-noop.c
 F:	lib/dma-virt.c
 F:	drivers/base/dma-mapping.c
 F:	drivers/base/dma-coherent.c
+F:	include/linux/dma-direct.h
 F:	include/linux/dma-mapping.h
 
 DME1737 HARDWARE MONITOR DRIVER
arch/Kconfig +4 -0
index 400b9e1b2f27..3edf118ad777 100644
@@ -938,6 +938,10 @@ config STRICT_MODULE_RWX
 	  and non-text memory will be made non-executable. This provides
 	  protection against certain security exploits (e.g. writing to text)
 
+# select if the architecture provides an asm/dma-direct.h header
+config ARCH_HAS_PHYS_TO_DMA
+	bool
+
 config ARCH_HAS_REFCOUNT
 	bool
 	help
arch/arm/Kconfig +1 -0
index 51c8df561077..00d889a37965 100644
@@ -8,6 +8,7 @@ config ARM
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_SET_MEMORY
+	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL
 	select ARCH_HAS_STRICT_MODULE_RWX if MMU
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
arch/arm/include/asm/dma-direct.h new file +36 -0
new file mode 100644
index 000000000000..5b0a8a421894
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ASM_ARM_DMA_DIRECT_H
+#define ASM_ARM_DMA_DIRECT_H 1
+
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	unsigned int offset = paddr & ~PAGE_MASK;
+	return pfn_to_dma(dev, __phys_to_pfn(paddr)) + offset;
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
+{
+	unsigned int offset = dev_addr & ~PAGE_MASK;
+	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
+}
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	u64 limit, mask;
+
+	if (!dev->dma_mask)
+		return 0;
+
+	mask = *dev->dma_mask;
+
+	limit = (mask + 1) & ~mask;
+	if (limit && size > limit)
+		return 0;
+
+	if ((addr | (addr + size - 1)) & ~mask)
+		return 0;
+
+	return 1;
+}
+
+#endif /* ASM_ARM_DMA_DIRECT_H */
arch/arm/include/asm/dma-mapping.h +0 -31
index daf837423a76..5fb1b7fbdfbe 100644
@@ -109,37 +109,6 @@ static inline bool is_device_dma_coherent(struct device *dev)
 	return dev->archdata.dma_coherent;
 }
 
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	unsigned int offset = paddr & ~PAGE_MASK;
-	return pfn_to_dma(dev, __phys_to_pfn(paddr)) + offset;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
-{
-	unsigned int offset = dev_addr & ~PAGE_MASK;
-	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
-}
-
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	u64 limit, mask;
-
-	if (!dev->dma_mask)
-		return 0;
-
-	mask = *dev->dma_mask;
-
-	limit = (mask + 1) & ~mask;
-	if (limit && size > limit)
-		return 0;
-
-	if ((addr | (addr + size - 1)) & ~mask)
-		return 0;
-
-	return 1;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size) { }
 
 /**
arch/arm64/include/asm/dma-mapping.h +0 -22
index eada887a93bf..400fa67d3b5a 100644
@@ -50,28 +50,6 @@ static inline bool is_device_dma_coherent(struct device *dev)
 	return dev->archdata.dma_coherent;
 }
 
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	dma_addr_t dev_addr = (dma_addr_t)paddr;
-
-	return dev_addr - ((dma_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
-{
-	phys_addr_t paddr = (phys_addr_t)dev_addr;
-
-	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
-}
-
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size)
 {
 }
arch/arm64/mm/dma-mapping.c +1 -1
index b45c5bcaeccb..f3a637b98487 100644
@@ -24,7 +24,7 @@
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/genalloc.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/dma-contiguous.h>
 #include <linux/vmalloc.h>
 #include <linux/swiotlb.h>
arch/ia64/include/asm/dma-mapping.h +0 -18
index c1bab526a046..eabee56d995c 100644
@@ -27,22 +27,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return platform_dma_get_ops(NULL);
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return 0;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr;
-}
-
 #endif /* _ASM_IA64_DMA_MAPPING_H */
arch/mips/Kconfig +2 -0
index 350a990fc719..4b0c26b2e9b7 100644
@@ -429,6 +429,7 @@ config MACH_LOONGSON32
 
 config MACH_LOONGSON64
 	bool "Loongson-2/3 family of machines"
+	select ARCH_HAS_PHYS_TO_DMA
 	select SYS_SUPPORTS_ZBOOT
 	help
 	  This enables the support of Loongson-2/3 family of machines.
@@ -877,6 +878,7 @@ config MIKROTIK_RB532
 config CAVIUM_OCTEON_SOC
 	bool "Cavium Networks Octeon SoC based boards"
 	select CEVT_R4K
+	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_PHYS_ADDR_T_64BIT
 	select DMA_COHERENT
 	select SYS_SUPPORTS_64BIT_KERNEL
arch/mips/include/asm/dma-direct.h new file +1 -0
new file mode 100644
index 000000000000..f32f15530aba
@@ -0,0 +1 @@
+#include <asm/dma-coherence.h>
arch/mips/include/asm/dma-mapping.h +0 -8
index 0d9418d264f9..676c14cfc580 100644
@@ -17,14 +17,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return mips_dma_map_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size <= *dev->dma_mask;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
 #define arch_setup_dma_ops arch_setup_dma_ops
arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h +8 -0
index 9110988b92a1..f00833acb626 100644
@@ -61,6 +61,14 @@ static inline void plat_post_dma_flush(struct device *dev)
 {
 }
 
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (!dev->dma_mask)
+		return false;
+
+	return addr + size <= *dev->dma_mask;
+}
+
 dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
 phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
 
arch/mips/include/asm/mach-generic/dma-coherence.h +0 -12
index 61addb1677e9..8ad7a40ca786 100644
@@ -70,16 +70,4 @@ static inline void plat_post_dma_flush(struct device *dev)
 }
 #endif
 
-#ifdef CONFIG_SWIOTLB
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr;
-}
-#endif
-
 #endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */
arch/mips/include/asm/mach-loongson64/dma-coherence.h +8 -0
index 1602a9e9e8c2..5cfda8f893e9 100644
@@ -17,6 +17,14 @@
 
 struct device;
 
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (!dev->dma_mask)
+		return false;
+
+	return addr + size <= *dev->dma_mask;
+}
+
 extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
 extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
 static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
arch/powerpc/Kconfig +1 -0
index c51e6ce42e7a..887285eb684a 100644
@@ -139,6 +139,7 @@ config PPC
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_HAS_PMEM_API                if PPC64
 	select ARCH_HAS_SCALED_CPUTIME		if VIRT_CPU_ACCOUNTING_NATIVE
 	select ARCH_HAS_SG_CHAIN
arch/powerpc/include/asm/dma-direct.h new file +29 -0
new file mode 100644
index 000000000000..a5b59c765426
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ASM_POWERPC_DMA_DIRECT_H
+#define ASM_POWERPC_DMA_DIRECT_H 1
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+#ifdef CONFIG_SWIOTLB
+	struct dev_archdata *sd = &dev->archdata;
+
+	if (sd->max_direct_dma_addr && addr + size > sd->max_direct_dma_addr)
+		return false;
+#endif
+
+	if (!dev->dma_mask)
+		return false;
+
+	return addr + size - 1 <= *dev->dma_mask;
+}
+
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	return paddr + get_dma_offset(dev);
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+	return daddr - get_dma_offset(dev);
+}
+#endif /* ASM_POWERPC_DMA_DIRECT_H */
arch/powerpc/include/asm/dma-mapping.h +0 -25
index 592c7f418aa0..f6ab51205a85 100644
@@ -112,31 +112,6 @@ extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
 extern u64 __dma_get_required_mask(struct device *dev);
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-#ifdef CONFIG_SWIOTLB
-	struct dev_archdata *sd = &dev->archdata;
-
-	if (sd->max_direct_dma_addr && addr + size > sd->max_direct_dma_addr)
-		return false;
-#endif
-
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr + get_dma_offset(dev);
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr - get_dma_offset(dev);
-}
-
 #define ARCH_HAS_DMA_MMAP_COHERENT
 
 #endif /* __KERNEL__ */
arch/tile/include/asm/dma-mapping.h +0 -18
index 97ad62878290..75b8aaa4e70b 100644
@@ -44,26 +44,8 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
 	dev->archdata.dma_offset = off;
 }
 
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return 0;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #define HAVE_ARCH_DMA_SET_MASK 1
 int dma_set_mask(struct device *dev, u64 mask);
 
arch/unicore32/include/asm/dma-mapping.h +0 -18
index ac608c2f6af6..5cb250bf2d8c 100644
@@ -25,24 +25,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &swiotlb_dma_map_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (dev && dev->dma_mask)
-		return addr + size - 1 <= *dev->dma_mask;
-
-	return 1;
-}
-
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return daddr;
-}
-
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
 #endif /* __KERNEL__ */
arch/x86/Kconfig +1 -0
index d4fc98c50378..f6f4328103c0 100644
@@ -54,6 +54,7 @@ config X86
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV			if X86_64
+	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_HAS_PMEM_API		if X86_64
 	# Causing hangs/crashes, see the commit that added this change for details.
 	select ARCH_HAS_REFCOUNT
arch/x86/include/asm/dma-direct.h new file +30 -0
new file mode 100644
index 000000000000..1295bc622ebe
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ASM_X86_DMA_DIRECT_H
+#define ASM_X86_DMA_DIRECT_H 1
+
+#include <linux/mem_encrypt.h>
+
+#ifdef CONFIG_X86_DMA_REMAP /* Platform code defines bridge-specific code */
+bool dma_capable(struct device *dev, dma_addr_t addr, size_t size);
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
+#else
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (!dev->dma_mask)
+		return 0;
+
+	return addr + size - 1 <= *dev->dma_mask;
+}
+
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	return __sme_set(paddr);
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+	return __sme_clr(daddr);
+}
+#endif /* CONFIG_X86_DMA_REMAP */
+#endif /* ASM_X86_DMA_DIRECT_H */
arch/x86/include/asm/dma-mapping.h +0 -26
index 0350d99bb8fd..dfdc9357a349 100644
@@ -12,7 +12,6 @@
 #include <asm/io.h>
 #include <asm/swiotlb.h>
 #include <linux/dma-contiguous.h>
-#include <linux/mem_encrypt.h>
 
 #ifdef CONFIG_ISA
 # define ISA_DMA_BIT_MASK DMA_BIT_MASK(24)
@@ -42,31 +41,6 @@ extern void dma_generic_free_coherent(struct device *dev, size_t size,
 				      void *vaddr, dma_addr_t dma_addr,
 				      unsigned long attrs);
 
-#ifdef CONFIG_X86_DMA_REMAP /* Platform code defines bridge-specific code */
-extern bool dma_capable(struct device *dev, dma_addr_t addr, size_t size);
-extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
-extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
-#else
-
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return 0;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return __sme_set(paddr);
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return __sme_clr(daddr);
-}
-#endif /* CONFIG_X86_DMA_REMAP */
-
 static inline unsigned long dma_alloc_coherent_mask(struct device *dev,
 						    gfp_t gfp)
 {
arch/x86/kernel/amd_gart_64.c +1 -0
index cc0e8bc0ea3f..ecd486cb06ab 100644
@@ -31,6 +31,7 @@
 #include <linux/io.h>
 #include <linux/gfp.h>
 #include <linux/atomic.h>
+#include <linux/dma-direct.h>
 #include <asm/mtrr.h>
 #include <asm/pgtable.h>
 #include <asm/proto.h>
arch/x86/kernel/pci-dma.c +1 -1
index 599d7462eccc..8439e6de6156 100644
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/dma-debug.h>
 #include <linux/dmar.h>
 #include <linux/export.h>
arch/x86/kernel/pci-nommu.c +1 -1
index 8ac9d1fe0373..8b8ff98486de 100644
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Fallback functions when the main IOMMU code is not compiled in. This
    code is roughly equivalent to i386. */
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
 #include <linux/string.h>
 #include <linux/gfp.h>
arch/x86/kernel/pci-swiotlb.c +1 -1
index 53bd05ea90d8..9d3e35c33d94 100644
@@ -6,7 +6,7 @@
 #include <linux/init.h>
 #include <linux/swiotlb.h>
 #include <linux/bootmem.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/mem_encrypt.h>
 
 #include <asm/iommu.h>
arch/x86/mm/mem_encrypt.c +1 -1
index d9a9e9fc75dd..764b916ef7da 100644
@@ -15,7 +15,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/mm.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/swiotlb.h>
 #include <linux/mem_encrypt.h>
 
arch/x86/pci/sta2x11-fixup.c +1 -0
index 53d600217973..75577c1490c4 100644
@@ -26,6 +26,7 @@
 #include <linux/pci_ids.h>
 #include <linux/export.h>
 #include <linux/list.h>
+#include <linux/dma-direct.h>
 #include <asm/iommu.h>
 
 #define STA2X11_SWIOTLB_SIZE (4*1024*1024)
arch/xtensa/include/asm/dma-mapping.h +0 -10
index 153bf2370988..44098800dad7 100644
@@ -23,14 +23,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &xtensa_dma_map_ops;
 }
 
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return (dma_addr_t)paddr;
-}
-
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return (phys_addr_t)daddr;
-}
-
 #endif	/* _XTENSA_DMA_MAPPING_H */
drivers/crypto/marvell/cesa.c +1 -0
index 293832488cc9..3a0c40081ffb 100644
@@ -24,6 +24,7 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/dma-direct.h> /* XXX: drivers shall never use this directly! */
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
drivers/mtd/nand/qcom_nandc.c +1 -0
index 2656c1ac5646..411cdfd12a85 100644
@@ -23,6 +23,7 @@
 #include <linux/of_device.h>
 #include <linux/delay.h>
 #include <linux/dma/qcom_bam_dma.h>
+#include <linux/dma-direct.h> /* XXX: drivers shall never use this directly! */
 
 /* NANDc reg offsets */
 #define	NAND_FLASH_CMD			0x00
drivers/xen/swiotlb-xen.c +1 -1
index 82fc54f8eb77..5bb72d3f8337 100644
@@ -36,7 +36,7 @@
 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
 
 #include <linux/bootmem.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/export.h>
 #include <xen/swiotlb-xen.h>
 #include <xen/page.h>
include/linux/dma-direct.h new file +32 -0
new file mode 100644
index 000000000000..2cc1b6558944
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_DMA_DIRECT_H
+#define _LINUX_DMA_DIRECT_H 1
+
+#include <linux/dma-mapping.h>
+
+#ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
+#include <asm/dma-direct.h>
+#else
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	dma_addr_t dev_addr = (dma_addr_t)paddr;
+
+	return dev_addr - ((dma_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
+{
+	phys_addr_t paddr = (phys_addr_t)dev_addr;
+
+	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
+}
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (!dev->dma_mask)
+		return false;
+
+	return addr + size - 1 <= *dev->dma_mask;
+}
+#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
+#endif /* _LINUX_DMA_DIRECT_H */
lib/swiotlb.c +1 -1
index cea19aaf303c..6583f3512386 100644
@@ -18,7 +18,7 @@
  */
 
 #include <linux/cache.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/mm.h>
 #include <linux/export.h>
 #include <linux/spinlock.h>
Signature · 1 line
2.14.2
#36 lore raw

PATCH 14/67 dma-mapping: move dma_mark_clean to dma-direct.h

In reply to Christoph Hellwig

And unlike the other helpers we don't require a <asm/dma-direct.h> as this helper is a special case for ia64 only, and this keeps it as simple as possible.

---
 arch/arm/include/asm/dma-mapping.h       | 2 --
 arch/arm64/include/asm/dma-mapping.h     | 4 ----
 arch/ia64/Kconfig                        | 1 +
 arch/ia64/include/asm/dma.h              | 2 --
 arch/mips/include/asm/dma-mapping.h      | 2 --
 arch/powerpc/include/asm/swiotlb.h       | 2 --
 arch/tile/include/asm/dma-mapping.h      | 2 --
 arch/unicore32/include/asm/dma-mapping.h | 2 --
 arch/x86/include/asm/swiotlb.h           | 2 --
 include/linux/dma-direct.h               | 9 +++++++++
 10 files changed, 10 insertions(+), 18 deletions(-)
arch/arm/include/asm/dma-mapping.h +0 -2
index 5fb1b7fbdfbe..e5d9020c9ee1 100644
@@ -109,8 +109,6 @@ static inline bool is_device_dma_coherent(struct device *dev)
 	return dev->archdata.dma_coherent;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size) { }
-
 /**
  * arm_dma_alloc - allocate consistent memory for DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
arch/arm64/include/asm/dma-mapping.h +0 -4
index 400fa67d3b5a..b7847eb8a7bb 100644
@@ -50,9 +50,5 @@ static inline bool is_device_dma_coherent(struct device *dev)
 	return dev->archdata.dma_coherent;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size)
-{
-}
-
 #endif	/* __KERNEL__ */
 #endif	/* __ASM_DMA_MAPPING_H */
arch/ia64/Kconfig +1 -0
index 49583c5a5d44..4d18fca885ee 100644
@@ -33,6 +33,7 @@ config IA64
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP
 	select HAVE_VIRT_CPU_ACCOUNTING
+	select ARCH_HAS_DMA_MARK_CLEAN
 	select ARCH_HAS_SG_CHAIN
 	select VIRT_TO_BUS
 	select ARCH_DISCARD_MEMBLOCK
arch/ia64/include/asm/dma.h +0 -2
index 186850eec934..23604d6a2cb2 100644
@@ -20,6 +20,4 @@ extern unsigned long MAX_DMA_ADDRESS;
 
 #define free_dma(x)
 
-void dma_mark_clean(void *addr, size_t size);
-
 #endif /* _ASM_IA64_DMA_H */
arch/mips/include/asm/dma-mapping.h +0 -2
index 676c14cfc580..886e75a383f2 100644
@@ -17,8 +17,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return mips_dma_map_ops;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 #define arch_setup_dma_ops arch_setup_dma_ops
 static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
 				      u64 size, const struct iommu_ops *iommu,
arch/powerpc/include/asm/swiotlb.h +0 -2
index 01d45a5fd00b..9341ee804d19 100644
@@ -15,8 +15,6 @@
 
 extern const struct dma_map_ops swiotlb_dma_ops;
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 extern unsigned int ppc_swiotlb_enable;
 int __init swiotlb_setup_bus_notifier(void);
 
arch/tile/include/asm/dma-mapping.h +0 -2
index 75b8aaa4e70b..d25fce101fc0 100644
@@ -44,8 +44,6 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
 	dev->archdata.dma_offset = off;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 #define HAVE_ARCH_DMA_SET_MASK 1
 int dma_set_mask(struct device *dev, u64 mask);
 
arch/unicore32/include/asm/dma-mapping.h +0 -2
index 5cb250bf2d8c..f2bfec273aa7 100644
@@ -25,7 +25,5 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &swiotlb_dma_map_ops;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 #endif /* __KERNEL__ */
 #endif
arch/x86/include/asm/swiotlb.h +0 -2
index bdf9aed40403..1c6a6cb230ff 100644
@@ -28,8 +28,6 @@ static inline void pci_swiotlb_late_init(void)
 }
 #endif
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 extern void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 					dma_addr_t *dma_handle, gfp_t flags,
 					unsigned long attrs);
include/linux/dma-direct.h +9 -0
index 2cc1b6558944..10e924b7cba7 100644
@@ -29,4 +29,13 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 	return addr + size - 1 <= *dev->dma_mask;
 }
 #endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
+
+#ifdef CONFIG_ARCH_HAS_DMA_MARK_CLEAN
+void dma_mark_clean(void *addr, size_t size);
+#else
+static inline void dma_mark_clean(void *addr, size_t size)
+{
+}
+#endif /* CONFIG_ARCH_HAS_DMA_MARK_CLEAN */
+
 #endif /* _LINUX_DMA_DIRECT_H */
Signature · 1 line
2.14.2
#37 lore raw

PATCH 14/67 dma-mapping: move dma_mark_clean to dma-direct.h

In reply to Christoph Hellwig

And unlike the other helpers we don't require a <asm/dma-direct.h> as this helper is a special case for ia64 only, and this keeps it as simple as possible.

---
 arch/arm/include/asm/dma-mapping.h       | 2 --
 arch/arm64/include/asm/dma-mapping.h     | 4 ----
 arch/ia64/Kconfig                        | 1 +
 arch/ia64/include/asm/dma.h              | 2 --
 arch/mips/include/asm/dma-mapping.h      | 2 --
 arch/powerpc/include/asm/swiotlb.h       | 2 --
 arch/tile/include/asm/dma-mapping.h      | 2 --
 arch/unicore32/include/asm/dma-mapping.h | 2 --
 arch/x86/include/asm/swiotlb.h           | 2 --
 include/linux/dma-direct.h               | 9 +++++++++
 10 files changed, 10 insertions(+), 18 deletions(-)
arch/arm/include/asm/dma-mapping.h +0 -2
index 5fb1b7fbdfbe..e5d9020c9ee1 100644
@@ -109,8 +109,6 @@ static inline bool is_device_dma_coherent(struct device *dev)
 	return dev->archdata.dma_coherent;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size) { }
-
 /**
  * arm_dma_alloc - allocate consistent memory for DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
arch/arm64/include/asm/dma-mapping.h +0 -4
index 400fa67d3b5a..b7847eb8a7bb 100644
@@ -50,9 +50,5 @@ static inline bool is_device_dma_coherent(struct device *dev)
 	return dev->archdata.dma_coherent;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size)
-{
-}
-
 #endif	/* __KERNEL__ */
 #endif	/* __ASM_DMA_MAPPING_H */
arch/ia64/Kconfig +1 -0
index 49583c5a5d44..4d18fca885ee 100644
@@ -33,6 +33,7 @@ config IA64
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP
 	select HAVE_VIRT_CPU_ACCOUNTING
+	select ARCH_HAS_DMA_MARK_CLEAN
 	select ARCH_HAS_SG_CHAIN
 	select VIRT_TO_BUS
 	select ARCH_DISCARD_MEMBLOCK
arch/ia64/include/asm/dma.h +0 -2
index 186850eec934..23604d6a2cb2 100644
@@ -20,6 +20,4 @@ extern unsigned long MAX_DMA_ADDRESS;
 
 #define free_dma(x)
 
-void dma_mark_clean(void *addr, size_t size);
-
 #endif /* _ASM_IA64_DMA_H */
arch/mips/include/asm/dma-mapping.h +0 -2
index 676c14cfc580..886e75a383f2 100644
@@ -17,8 +17,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return mips_dma_map_ops;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 #define arch_setup_dma_ops arch_setup_dma_ops
 static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
 				      u64 size, const struct iommu_ops *iommu,
arch/powerpc/include/asm/swiotlb.h +0 -2
index 01d45a5fd00b..9341ee804d19 100644
@@ -15,8 +15,6 @@
 
 extern const struct dma_map_ops swiotlb_dma_ops;
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 extern unsigned int ppc_swiotlb_enable;
 int __init swiotlb_setup_bus_notifier(void);
 
arch/tile/include/asm/dma-mapping.h +0 -2
index 75b8aaa4e70b..d25fce101fc0 100644
@@ -44,8 +44,6 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
 	dev->archdata.dma_offset = off;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 #define HAVE_ARCH_DMA_SET_MASK 1
 int dma_set_mask(struct device *dev, u64 mask);
 
arch/unicore32/include/asm/dma-mapping.h +0 -2
index 5cb250bf2d8c..f2bfec273aa7 100644
@@ -25,7 +25,5 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return &swiotlb_dma_map_ops;
 }
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 #endif /* __KERNEL__ */
 #endif
arch/x86/include/asm/swiotlb.h +0 -2
index bdf9aed40403..1c6a6cb230ff 100644
@@ -28,8 +28,6 @@ static inline void pci_swiotlb_late_init(void)
 }
 #endif
 
-static inline void dma_mark_clean(void *addr, size_t size) {}
-
 extern void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 					dma_addr_t *dma_handle, gfp_t flags,
 					unsigned long attrs);
include/linux/dma-direct.h +9 -0
index 2cc1b6558944..10e924b7cba7 100644
@@ -29,4 +29,13 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 	return addr + size - 1 <= *dev->dma_mask;
 }
 #endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
+
+#ifdef CONFIG_ARCH_HAS_DMA_MARK_CLEAN
+void dma_mark_clean(void *addr, size_t size);
+#else
+static inline void dma_mark_clean(void *addr, size_t size)
+{
+}
+#endif /* CONFIG_ARCH_HAS_DMA_MARK_CLEAN */
+
 #endif /* _LINUX_DMA_DIRECT_H */
Signature · 1 line
2.14.2
#38 lore raw

PATCH 15/67 hexagon: use the generic dma_capable helper

In reply to Christoph Hellwig
---
 arch/hexagon/include/asm/dma-mapping.h | 7 -------
 arch/hexagon/kernel/dma.c              | 1 +
 2 files changed, 1 insertion(+), 7 deletions(-)
arch/hexagon/include/asm/dma-mapping.h +0 -7
index 5208de242e79..263f6acbfb0f 100644
@@ -37,11 +37,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return dma_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return 0;
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #endif
arch/hexagon/kernel/dma.c +1 -0
index 3683bb9c05a2..c1d24e37807c 100644
@@ -19,6 +19,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/bootmem.h>
 #include <linux/genalloc.h>
 #include <asm/dma-mapping.h>
Signature · 1 line
2.14.2
#39 lore raw

PATCH 15/67 hexagon: use the generic dma_capable helper

In reply to Christoph Hellwig
---
 arch/hexagon/include/asm/dma-mapping.h | 7 -------
 arch/hexagon/kernel/dma.c              | 1 +
 2 files changed, 1 insertion(+), 7 deletions(-)
arch/hexagon/include/asm/dma-mapping.h +0 -7
index 5208de242e79..263f6acbfb0f 100644
@@ -37,11 +37,4 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return dma_ops;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return 0;
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 #endif
arch/hexagon/kernel/dma.c +1 -0
index 3683bb9c05a2..c1d24e37807c 100644
@@ -19,6 +19,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/bootmem.h>
 #include <linux/genalloc.h>
 #include <asm/dma-mapping.h>
Signature · 1 line
2.14.2
#40 lore raw

PATCH 16/67 powerpc: rename dma_direct_ to dma_nommu_

In reply to Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

---
 arch/powerpc/include/asm/dma-mapping.h    |  8 ++--
 arch/powerpc/kernel/dma-iommu.c           |  2 +-
 arch/powerpc/kernel/dma-swiotlb.c         |  6 +--
 arch/powerpc/kernel/dma.c                 | 68 +++++++++++++++----------------
 arch/powerpc/kernel/pci-common.c          |  2 +-
 arch/powerpc/kernel/setup-common.c        |  2 +-
 arch/powerpc/platforms/cell/iommu.c       | 28 ++++++-------
 arch/powerpc/platforms/pasemi/iommu.c     |  2 +-
 arch/powerpc/platforms/pasemi/setup.c     |  2 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |  4 +-
 arch/powerpc/platforms/pseries/iommu.c    |  2 +-
 arch/powerpc/platforms/pseries/vio.c      |  2 +-
 arch/powerpc/sysdev/dart_iommu.c          |  4 +-
 arch/powerpc/sysdev/fsl_pci.c             |  2 +-
 drivers/misc/cxl/vphb.c                   |  2 +-
 15 files changed, 68 insertions(+), 68 deletions(-)
arch/powerpc/include/asm/dma-mapping.h +4 -4
index f6ab51205a85..8fa394520af6 100644
@@ -19,13 +19,13 @@
 #include <asm/swiotlb.h>
 
 /* Some dma direct funcs must be visible for use in other dma_ops */
-extern void *__dma_direct_alloc_coherent(struct device *dev, size_t size,
+extern void *__dma_nommu_alloc_coherent(struct device *dev, size_t size,
 					 dma_addr_t *dma_handle, gfp_t flag,
 					 unsigned long attrs);
-extern void __dma_direct_free_coherent(struct device *dev, size_t size,
+extern void __dma_nommu_free_coherent(struct device *dev, size_t size,
 				       void *vaddr, dma_addr_t dma_handle,
 				       unsigned long attrs);
-extern int dma_direct_mmap_coherent(struct device *dev,
+extern int dma_nommu_mmap_coherent(struct device *dev,
 				    struct vm_area_struct *vma,
 				    void *cpu_addr, dma_addr_t handle,
 				    size_t size, unsigned long attrs);
@@ -73,7 +73,7 @@ static inline unsigned long device_to_mask(struct device *dev)
 #ifdef CONFIG_PPC64
 extern struct dma_map_ops dma_iommu_ops;
 #endif
-extern const struct dma_map_ops dma_direct_ops;
+extern const struct dma_map_ops dma_nommu_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
arch/powerpc/kernel/dma-iommu.c +1 -1
index 66f33e7f8d40..f9fe2080ceb9 100644
@@ -114,7 +114,7 @@ int dma_iommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
 struct dma_map_ops dma_iommu_ops = {
 	.alloc			= dma_iommu_alloc_coherent,
 	.free			= dma_iommu_free_coherent,
-	.mmap			= dma_direct_mmap_coherent,
+	.mmap			= dma_nommu_mmap_coherent,
 	.map_sg			= dma_iommu_map_sg,
 	.unmap_sg		= dma_iommu_unmap_sg,
 	.dma_supported		= dma_iommu_dma_supported,
arch/powerpc/kernel/dma-swiotlb.c +3 -3
index d0ea7860e02b..f1e99b9cee97 100644
@@ -47,9 +47,9 @@ static u64 swiotlb_powerpc_get_required(struct device *dev)
  * for everything else.
  */
 const struct dma_map_ops swiotlb_dma_ops = {
-	.alloc = __dma_direct_alloc_coherent,
-	.free = __dma_direct_free_coherent,
-	.mmap = dma_direct_mmap_coherent,
+	.alloc = __dma_nommu_alloc_coherent,
+	.free = __dma_nommu_free_coherent,
+	.mmap = dma_nommu_mmap_coherent,
 	.map_sg = swiotlb_map_sg_attrs,
 	.unmap_sg = swiotlb_unmap_sg_attrs,
 	.dma_supported = swiotlb_dma_supported,
arch/powerpc/kernel/dma.c +34 -34

172 lines not on this page · raw message

arch/powerpc/kernel/pci-common.c +1 -1
index 0ac7aa346c69..590f4d0a6cb1 100644
@@ -60,7 +60,7 @@ resource_size_t isa_mem_base;
 EXPORT_SYMBOL(isa_mem_base);
 
 
-static const struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
+static const struct dma_map_ops *pci_dma_ops = &dma_nommu_ops;
 
 void set_pci_dma_ops(const struct dma_map_ops *dma_ops)
 {
arch/powerpc/kernel/setup-common.c +1 -1
index 9d213542a48b..9b89df1e71ab 100644
@@ -791,7 +791,7 @@ void arch_setup_pdev_archdata(struct platform_device *pdev)
 {
 	pdev->archdata.dma_mask = DMA_BIT_MASK(32);
 	pdev->dev.dma_mask = &pdev->archdata.dma_mask;
- 	set_dma_ops(&pdev->dev, &dma_direct_ops);
+ 	set_dma_ops(&pdev->dev, &dma_nommu_ops);
 }
 
 static __init void print_system_info(void)
arch/powerpc/platforms/cell/iommu.c +14 -14
index 4b91ad08eefd..12352a58072a 100644
@@ -541,7 +541,7 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
 	return NULL;
 }
 
-static unsigned long cell_dma_direct_offset;
+static unsigned long cell_dma_nommu_offset;
 
 static unsigned long dma_iommu_fixed_base;
 
@@ -580,7 +580,7 @@ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
 					    device_to_mask(dev), flag,
 					    dev_to_node(dev));
 	else
-		return dma_direct_ops.alloc(dev, size, dma_handle, flag,
+		return dma_nommu_ops.alloc(dev, size, dma_handle, flag,
 					    attrs);
 }
 
@@ -592,7 +592,7 @@ static void dma_fixed_free_coherent(struct device *dev, size_t size,
 		iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr,
 				    dma_handle);
 	else
-		dma_direct_ops.free(dev, size, vaddr, dma_handle, attrs);
+		dma_nommu_ops.free(dev, size, vaddr, dma_handle, attrs);
 }
 
 static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page,
@@ -601,7 +601,7 @@ static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page,
 				     unsigned long attrs)
 {
 	if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING))
-		return dma_direct_ops.map_page(dev, page, offset, size,
+		return dma_nommu_ops.map_page(dev, page, offset, size,
 					       direction, attrs);
 	else
 		return iommu_map_page(dev, cell_get_iommu_table(dev), page,
@@ -614,7 +614,7 @@ static void dma_fixed_unmap_page(struct device *dev, dma_addr_t dma_addr,
 				 unsigned long attrs)
 {
 	if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING))
-		dma_direct_ops.unmap_page(dev, dma_addr, size, direction,
+		dma_nommu_ops.unmap_page(dev, dma_addr, size, direction,
 					  attrs);
 	else
 		iommu_unmap_page(cell_get_iommu_table(dev), dma_addr, size,
@@ -626,7 +626,7 @@ static int dma_fixed_map_sg(struct device *dev, struct scatterlist *sg,
 			   unsigned long attrs)
 {
 	if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING))
-		return dma_direct_ops.map_sg(dev, sg, nents, direction, attrs);
+		return dma_nommu_ops.map_sg(dev, sg, nents, direction, attrs);
 	else
 		return ppc_iommu_map_sg(dev, cell_get_iommu_table(dev), sg,
 					nents, device_to_mask(dev),
@@ -638,7 +638,7 @@ static void dma_fixed_unmap_sg(struct device *dev, struct scatterlist *sg,
 			       unsigned long attrs)
 {
 	if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING))
-		dma_direct_ops.unmap_sg(dev, sg, nents, direction, attrs);
+		dma_nommu_ops.unmap_sg(dev, sg, nents, direction, attrs);
 	else
 		ppc_iommu_unmap_sg(cell_get_iommu_table(dev), sg, nents,
 				   direction, attrs);
@@ -661,8 +661,8 @@ static void cell_dma_dev_setup(struct device *dev)
 {
 	if (get_pci_dma_ops() == &dma_iommu_ops)
 		set_iommu_table_base(dev, cell_get_iommu_table(dev));
-	else if (get_pci_dma_ops() == &dma_direct_ops)
-		set_dma_offset(dev, cell_dma_direct_offset);
+	else if (get_pci_dma_ops() == &dma_nommu_ops)
+		set_dma_offset(dev, cell_dma_nommu_offset);
 	else
 		BUG();
 }
@@ -810,14 +810,14 @@ static int __init cell_iommu_init_disabled(void)
 	unsigned long base = 0, size;
 
 	/* When no iommu is present, we use direct DMA ops */
-	set_pci_dma_ops(&dma_direct_ops);
+	set_pci_dma_ops(&dma_nommu_ops);
 
 	/* First make sure all IOC translation is turned off */
 	cell_disable_iommus();
 
 	/* If we have no Axon, we set up the spider DMA magic offset */
 	if (of_find_node_by_name(NULL, "axon") == NULL)
-		cell_dma_direct_offset = SPIDER_DMA_OFFSET;
+		cell_dma_nommu_offset = SPIDER_DMA_OFFSET;
 
 	/* Now we need to check to see where the memory is mapped
 	 * in PCI space. We assume that all busses use the same dma
@@ -851,13 +851,13 @@ static int __init cell_iommu_init_disabled(void)
 		return -ENODEV;
 	}
 
-	cell_dma_direct_offset += base;
+	cell_dma_nommu_offset += base;
 
-	if (cell_dma_direct_offset != 0)
+	if (cell_dma_nommu_offset != 0)
 		cell_pci_controller_ops.dma_dev_setup = cell_pci_dma_dev_setup;
 
 	printk("iommu: disabled, direct DMA offset is 0x%lx\n",
-	       cell_dma_direct_offset);
+	       cell_dma_nommu_offset);
 
 	return 0;
 }
arch/powerpc/platforms/pasemi/iommu.c +1 -1
index 7fec04de27fc..78b80cbd9768 100644
@@ -186,7 +186,7 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
 	 */
 	if (dev->vendor == 0x1959 && dev->device == 0xa007 &&
 	    !firmware_has_feature(FW_FEATURE_LPAR)) {
-		dev->dev.dma_ops = &dma_direct_ops;
+		dev->dev.dma_ops = &dma_nommu_ops;
 		/*
 		 * Set the coherent DMA mask to prevent the iommu
 		 * being used unnecessarily
arch/powerpc/platforms/pasemi/setup.c +1 -1
index c4a3e93dc324..d0b8ae53660d 100644
@@ -363,7 +363,7 @@ static int pcmcia_notify(struct notifier_block *nb, unsigned long action,
 		return 0;
 
 	/* We use the direct ops for localbus */
-	dev->dma_ops = &dma_direct_ops;
+	dev->dma_ops = &dma_nommu_ops;
 
 	return 0;
 }
arch/powerpc/platforms/powernv/pci-ioda.c +2 -2
index 749055553064..9582aeb1fe4c 100644
@@ -1850,7 +1850,7 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
 
 	if (bypass) {
 		dev_info(&pdev->dev, "Using 64-bit DMA iommu bypass\n");
-		set_dma_ops(&pdev->dev, &dma_direct_ops);
+		set_dma_ops(&pdev->dev, &dma_nommu_ops);
 	} else {
 		/*
 		 * If the device can't set the TCE bypass bit but still wants
@@ -1868,7 +1868,7 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
 				return rc;
 			/* 4GB offset bypasses 32-bit space */
 			set_dma_offset(&pdev->dev, (1ULL << 32));
-			set_dma_ops(&pdev->dev, &dma_direct_ops);
+			set_dma_ops(&pdev->dev, &dma_nommu_ops);
 		} else if (dma_mask >> 32 && dma_mask != DMA_BIT_MASK(64)) {
 			/*
 			 * Fail the request if a DMA mask between 32 and 64 bits
arch/powerpc/platforms/pseries/iommu.c +1 -1
index 69921f72e2da..eaa11334fc8c 100644
@@ -1231,7 +1231,7 @@ static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)
 			if (dma_offset != 0) {
 				dev_info(dev, "Using 64-bit direct DMA at offset %llx\n", dma_offset);
 				set_dma_offset(dev, dma_offset);
-				set_dma_ops(dev, &dma_direct_ops);
+				set_dma_ops(dev, &dma_nommu_ops);
 				ddw_enabled = true;
 			}
 		}
arch/powerpc/platforms/pseries/vio.c +1 -1
index d86938260a86..49e04ec19238 100644
@@ -618,7 +618,7 @@ static u64 vio_dma_get_required_mask(struct device *dev)
 static const struct dma_map_ops vio_dma_mapping_ops = {
 	.alloc             = vio_dma_iommu_alloc_coherent,
 	.free              = vio_dma_iommu_free_coherent,
-	.mmap		   = dma_direct_mmap_coherent,
+	.mmap		   = dma_nommu_mmap_coherent,
 	.map_sg            = vio_dma_iommu_map_sg,
 	.unmap_sg          = vio_dma_iommu_unmap_sg,
 	.map_page          = vio_dma_iommu_map_page,
arch/powerpc/sysdev/dart_iommu.c +2 -2
index 3573d54b2770..a6198d4f0f03 100644
@@ -402,7 +402,7 @@ static int dart_dma_set_mask(struct device *dev, u64 dma_mask)
 	 */
 	if (dart_device_on_pcie(dev) && dma_mask >= DMA_BIT_MASK(40)) {
 		dev_info(dev, "Using 64-bit DMA iommu bypass\n");
-		set_dma_ops(dev, &dma_direct_ops);
+		set_dma_ops(dev, &dma_nommu_ops);
 	} else {
 		dev_info(dev, "Using 32-bit DMA via iommu\n");
 		set_dma_ops(dev, &dma_iommu_ops);
@@ -446,7 +446,7 @@ void __init iommu_init_early_dart(struct pci_controller_ops *controller_ops)
 	controller_ops->dma_bus_setup = NULL;
 
 	/* Setup pci_dma ops */
-	set_pci_dma_ops(&dma_direct_ops);
+	set_pci_dma_ops(&dma_nommu_ops);
 }
 
 #ifdef CONFIG_PM
arch/powerpc/sysdev/fsl_pci.c +1 -1
index 22d98057f773..e4d0133bbeeb 100644
@@ -135,7 +135,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 	 * mapping that allows addressing any RAM address from across PCI.
 	 */
 	if (dev_is_pci(dev) && dma_mask >= pci64_dma_offset * 2 - 1) {
-		set_dma_ops(dev, &dma_direct_ops);
+		set_dma_ops(dev, &dma_nommu_ops);
 		set_dma_offset(dev, pci64_dma_offset);
 	}
 
drivers/misc/cxl/vphb.c +1 -1
index 512a4897dbf6..7fd0bdc1436a 100644
@@ -54,7 +54,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
 		return false;
 	}
 
-	set_dma_ops(&dev->dev, &dma_direct_ops);
+	set_dma_ops(&dev->dev, &dma_nommu_ops);
 	set_dma_offset(&dev->dev, PAGE_OFFSET);
 
 	return _cxl_pci_associate_default_context(dev, afu);
Signature · 1 line
2.14.2
#41 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

cheers

#42 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

Quoted 11 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

"identity"?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#43 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

Quoted 6 lines · Geert Uytterhoeven
Quoted 5 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

Quoted 8 lines
Quoted 6 lines

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

"identity"?

I think that would be wrong, but thanks for trying to help :)

The address on the device side is sometimes (often?) offset from the CPU address. So eg. the device can DMA to RAM address 0x0 using address 0x800000000000000.

Identity would imply 0 == 0 etc.

I think "bijective" is the correct term, but that's probably a bit esoteric.

cheers

#44 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

Hi Michael,

Quoted 19 lines · Michael Ellerman
Quoted 6 lines · Geert Uytterhoeven
Quoted 5 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

Quoted 8 lines
Quoted 6 lines

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

"identity"?

I think that would be wrong, but thanks for trying to help :)

Quoted 8 lines

The address on the device side is sometimes (often?) offset from the CPU address. So eg. the device can DMA to RAM address 0x0 using address 0x800000000000000.

Identity would imply 0 == 0 etc.

I think "bijective" is the correct term, but that's probably a bit esoteric.

OK, didn't know about the offset.
Then "linear" is what we tend to use, right?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#45 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

Hi All,

Quoted 26 lines · Geert Uytterhoeven

Hi Michael,

Quoted 23 lines · Michael Ellerman
Quoted 6 lines · Geert Uytterhoeven
Quoted 5 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

Quoted 8 lines
Quoted 6 lines

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

"identity"?

I think that would be wrong, but thanks for trying to help :)

The address on the device side is sometimes (often?) offset from the CPU address. So eg. the device can DMA to RAM address 0x0 using address 0x800000000000000.

Quoted 7 lines
Quoted 4 lines

Identity would imply 0 == 0 etc.

I think "bijective" is the correct term, but that's probably a bit esoteric.

OK, didn't know about the offset.
Then "linear" is what we tend to use, right?

If this is indeed a linear mapping, can we just remove this and replace it with the new "generic" mapping being introduced by this patchset?

Thanks,

Signature · 4 lines
Julian Calaby

Email: [email protected]
Profile: http://www.google.com/profiles/julian.calaby/
#46 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

Quoted 3 lines · Julian Calaby

If this is indeed a linear mapping, can we just remove this and replace it with the new "generic" mapping being introduced by this patchset?

That is the long-term plan. But as the powerpc one includes support for non-coherent DMA it will have to wait for the next batch.

#47 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

In reply to Julian Calaby
Quoted 3 lines · Julian Calaby

If this is indeed a linear mapping, can we just remove this and replace it with the new "generic" mapping being introduced by this patchset?

That is the long-term plan. But as the powerpc one includes support for non-coherent DMA it will have to wait for the next batch.

#48 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

In reply to Michael Ellerman

Hi Michael,

Quoted 19 lines · Michael Ellerman
Quoted 6 lines · Geert Uytterhoeven
Quoted 5 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

Quoted 8 lines
Quoted 6 lines

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

"identity"?

I think that would be wrong, but thanks for trying to help :)

Quoted 8 lines

The address on the device side is sometimes (often?) offset from the CPU address. So eg. the device can DMA to RAM address 0x0 using address 0x800000000000000.

Identity would imply 0 == 0 etc.

I think "bijective" is the correct term, but that's probably a bit esoteric.

OK, didn't know about the offset.
Then "linear" is what we tend to use, right?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#49 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

In reply to Michael Ellerman
Quoted 11 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

"identity"?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#50 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

In reply to Michael Ellerman
Quoted 11 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

It seems like a nice counter part to the dma_iommu_ops used just about anywhere else in ppc.

But I'll happily take any maintainer bike shed decision for the next series. Remember that in a merge window or two it will hopefully go away in favor of the new generic dma_direct ops.

#51 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

Quoted 13 lines · Christoph Hellwig
Quoted 11 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

Quoted 6 lines

It seems like a nice counter part to the dma_iommu_ops used just about anywhere else in ppc.

But I'll happily take any maintainer bike shed decision for the next series. Remember that in a merge window or two it will hopefully go away in favor of the new generic dma_direct ops.

Michael, please suggest what name you want for the next iteration, I don't want to hold up the series on a naming bikeshed.

#52 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

In reply to Christoph Hellwig
Quoted 13 lines · Christoph Hellwig
Quoted 11 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

Quoted 6 lines

It seems like a nice counter part to the dma_iommu_ops used just about anywhere else in ppc.

But I'll happily take any maintainer bike shed decision for the next series. Remember that in a merge window or two it will hopefully go away in favor of the new generic dma_direct ops.

Michael, please suggest what name you want for the next iteration, I don't want to hold up the series on a naming bikeshed.

#53 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

In reply to Michael Ellerman
Quoted 11 lines · Michael Ellerman
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

It seems like a nice counter part to the dma_iommu_ops used just about anywhere else in ppc.

But I'll happily take any maintainer bike shed decision for the next series. Remember that in a merge window or two it will hopefully go away in favor of the new generic dma_direct ops.

#54 lore raw

Re: [PATCH 16/67] powerpc: rename dma_direct_ to dma_nommu_

In reply to Christoph Hellwig
Quoted 2 lines · Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

I'm not a fan of "nommu". Some of the users of direct ops *are* using an IOMMU, they're just setting up a 1:1 mapping once at init time, rather than mapping dynamically.

Though I don't have a good idea for a better name, maybe "1to1", "linear", "premapped" ?

cheers

#55 lore raw

PATCH 16/67 powerpc: rename dma_direct_ to dma_nommu_

In reply to Christoph Hellwig

We want to use the dma_direct_ namespace for a generic implementation, so rename powerpc to the second best choice: dma_nommu_.

---
 arch/powerpc/include/asm/dma-mapping.h    |  8 ++--
 arch/powerpc/kernel/dma-iommu.c           |  2 +-
 arch/powerpc/kernel/dma-swiotlb.c         |  6 +--
 arch/powerpc/kernel/dma.c                 | 68 +++++++++++++++----------------
 arch/powerpc/kernel/pci-common.c          |  2 +-
 arch/powerpc/kernel/setup-common.c        |  2 +-
 arch/powerpc/platforms/cell/iommu.c       | 28 ++++++-------
 arch/powerpc/platforms/pasemi/iommu.c     |  2 +-
 arch/powerpc/platforms/pasemi/setup.c     |  2 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |  4 +-
 arch/powerpc/platforms/pseries/iommu.c    |  2 +-
 arch/powerpc/platforms/pseries/vio.c      |  2 +-
 arch/powerpc/sysdev/dart_iommu.c          |  4 +-
 arch/powerpc/sysdev/fsl_pci.c             |  2 +-
 drivers/misc/cxl/vphb.c                   |  2 +-
 15 files changed, 68 insertions(+), 68 deletions(-)
arch/powerpc/include/asm/dma-mapping.h +4 -4
index f6ab51205a85..8fa394520af6 100644
@@ -19,13 +19,13 @@
 #include <asm/swiotlb.h>
 
 /* Some dma direct funcs must be visible for use in other dma_ops */
-extern void *__dma_direct_alloc_coherent(struct device *dev, size_t size,
+extern void *__dma_nommu_alloc_coherent(struct device *dev, size_t size,
 					 dma_addr_t *dma_handle, gfp_t flag,
 					 unsigned long attrs);
-extern void __dma_direct_free_coherent(struct device *dev, size_t size,
+extern void __dma_nommu_free_coherent(struct device *dev, size_t size,
 				       void *vaddr, dma_addr_t dma_handle,
 				       unsigned long attrs);
-extern int dma_direct_mmap_coherent(struct device *dev,
+extern int dma_nommu_mmap_coherent(struct device *dev,
 				    struct vm_area_struct *vma,
 				    void *cpu_addr, dma_addr_t handle,
 				    size_t size, unsigned long attrs);
@@ -73,7 +73,7 @@ static inline unsigned long device_to_mask(struct device *dev)
 #ifdef CONFIG_PPC64
 extern struct dma_map_ops dma_iommu_ops;
 #endif
-extern const struct dma_map_ops dma_direct_ops;
+extern const struct dma_map_ops dma_nommu_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
arch/powerpc/kernel/dma-iommu.c +1 -1
index 66f33e7f8d40..f9fe2080ceb9 100644
@@ -114,7 +114,7 @@ int dma_iommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
 struct dma_map_ops dma_iommu_ops = {
 	.alloc			= dma_iommu_alloc_coherent,
 	.free			= dma_iommu_free_coherent,
-	.mmap			= dma_direct_mmap_coherent,
+	.mmap			= dma_nommu_mmap_coherent,
 	.map_sg			= dma_iommu_map_sg,
 	.unmap_sg		= dma_iommu_unmap_sg,
 	.dma_supported		= dma_iommu_dma_supported,
arch/powerpc/kernel/dma-swiotlb.c +3 -3
index d0ea7860e02b..f1e99b9cee97 100644
@@ -47,9 +47,9 @@ static u64 swiotlb_powerpc_get_required(struct device *dev)
  * for everything else.
  */
 const struct dma_map_ops swiotlb_dma_ops = {
-	.alloc = __dma_direct_alloc_coherent,
-	.free = __dma_direct_free_coherent,
-	.mmap = dma_direct_mmap_coherent,
+	.alloc = __dma_nommu_alloc_coherent,
+	.free = __dma_nommu_free_coherent,
+	.mmap = dma_nommu_mmap_coherent,
 	.map_sg = swiotlb_map_sg_attrs,
 	.unmap_sg = swiotlb_unmap_sg_attrs,
 	.dma_supported = swiotlb_dma_supported,
arch/powerpc/kernel/dma.c +34 -34

172 lines not on this page · raw message

arch/powerpc/kernel/pci-common.c +1 -1
index 0ac7aa346c69..590f4d0a6cb1 100644
@@ -60,7 +60,7 @@ resource_size_t isa_mem_base;
 EXPORT_SYMBOL(isa_mem_base);
 
 
-static const struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
+static const struct dma_map_ops *pci_dma_ops = &dma_nommu_ops;
 
 void set_pci_dma_ops(const struct dma_map_ops *dma_ops)
 {
arch/powerpc/kernel/setup-common.c +1 -1
index 9d213542a48b..9b89df1e71ab 100644
@@ -791,7 +791,7 @@ void arch_setup_pdev_archdata(struct platform_device *pdev)
 {
 	pdev->archdata.dma_mask = DMA_BIT_MASK(32);
 	pdev->dev.dma_mask = &pdev->archdata.dma_mask;
- 	set_dma_ops(&pdev->dev, &dma_direct_ops);
+ 	set_dma_ops(&pdev->dev, &dma_nommu_ops);
 }
 
 static __init void print_system_info(void)
arch/powerpc/platforms/cell/iommu.c +14 -14
index 4b91ad08eefd..12352a58072a 100644
@@ -541,7 +541,7 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
 	return NULL;
 }
 
-static unsigned long cell_dma_direct_offset;
+static unsigned long cell_dma_nommu_offset;
 
 static unsigned long dma_iommu_fixed_base;
 
@@ -580,7 +580,7 @@ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
 					    device_to_mask(dev), flag,
 					    dev_to_node(dev));
 	else
-		return dma_direct_ops.alloc(dev, size, dma_handle, flag,
+		return dma_nommu_ops.alloc(dev, size, dma_handle, flag,
 					    attrs);
 }
 
@@ -592,7 +592,7 @@ static void dma_fixed_free_coherent(struct device *dev, size_t size,
 		iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr,
 				    dma_handle);
 	else
-		dma_direct_ops.free(dev, size, vaddr, dma_handle, attrs);
+		dma_nommu_ops.free(dev, size, vaddr, dma_handle, attrs);
 }
 
 static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page,
@@ -601,7 +601,7 @@ static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page,
 				     unsigned long attrs)
 {
 	if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING))
-		return dma_direct_ops.map_page(dev, page, offset, size,
+		return dma_nommu_ops.map_page(dev, page, offset, size,
 					       direction, attrs);
 	else
 		return iommu_map_page(dev, cell_get_iommu_table(dev), page,
@@ -614,7 +614,7 @@ static void dma_fixed_unmap_page(struct device *dev, dma_addr_t dma_addr,
 				 unsigned long attrs)
 {
 	if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING))
-		dma_direct_ops.unmap_page(dev, dma_addr, size, direction,
+		dma_nommu_ops.unmap_page(dev, dma_addr, size, direction,
 					  attrs);
 	else
 		iommu_unmap_page(cell_get_iommu_table(dev), dma_addr, size,
@@ -626,7 +626,7 @@ static int dma_fixed_map_sg(struct device *dev, struct scatterlist *sg,
 			   unsigned long attrs)
 {
 	if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING))
-		return dma_direct_ops.map_sg(dev, sg, nents, direction, attrs);
+		return dma_nommu_ops.map_sg(dev, sg, nents, direction, attrs);
 	else
 		return ppc_iommu_map_sg(dev, cell_get_iommu_table(dev), sg,
 					nents, device_to_mask(dev),
@@ -638,7 +638,7 @@ static void dma_fixed_unmap_sg(struct device *dev, struct scatterlist *sg,
 			       unsigned long attrs)
 {
 	if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING))
-		dma_direct_ops.unmap_sg(dev, sg, nents, direction, attrs);
+		dma_nommu_ops.unmap_sg(dev, sg, nents, direction, attrs);
 	else
 		ppc_iommu_unmap_sg(cell_get_iommu_table(dev), sg, nents,
 				   direction, attrs);
@@ -661,8 +661,8 @@ static void cell_dma_dev_setup(struct device *dev)
 {
 	if (get_pci_dma_ops() == &dma_iommu_ops)
 		set_iommu_table_base(dev, cell_get_iommu_table(dev));
-	else if (get_pci_dma_ops() == &dma_direct_ops)
-		set_dma_offset(dev, cell_dma_direct_offset);
+	else if (get_pci_dma_ops() == &dma_nommu_ops)
+		set_dma_offset(dev, cell_dma_nommu_offset);
 	else
 		BUG();
 }
@@ -810,14 +810,14 @@ static int __init cell_iommu_init_disabled(void)
 	unsigned long base = 0, size;
 
 	/* When no iommu is present, we use direct DMA ops */
-	set_pci_dma_ops(&dma_direct_ops);
+	set_pci_dma_ops(&dma_nommu_ops);
 
 	/* First make sure all IOC translation is turned off */
 	cell_disable_iommus();
 
 	/* If we have no Axon, we set up the spider DMA magic offset */
 	if (of_find_node_by_name(NULL, "axon") == NULL)
-		cell_dma_direct_offset = SPIDER_DMA_OFFSET;
+		cell_dma_nommu_offset = SPIDER_DMA_OFFSET;
 
 	/* Now we need to check to see where the memory is mapped
 	 * in PCI space. We assume that all busses use the same dma
@@ -851,13 +851,13 @@ static int __init cell_iommu_init_disabled(void)
 		return -ENODEV;
 	}
 
-	cell_dma_direct_offset += base;
+	cell_dma_nommu_offset += base;
 
-	if (cell_dma_direct_offset != 0)
+	if (cell_dma_nommu_offset != 0)
 		cell_pci_controller_ops.dma_dev_setup = cell_pci_dma_dev_setup;
 
 	printk("iommu: disabled, direct DMA offset is 0x%lx\n",
-	       cell_dma_direct_offset);
+	       cell_dma_nommu_offset);
 
 	return 0;
 }
arch/powerpc/platforms/pasemi/iommu.c +1 -1
index 7fec04de27fc..78b80cbd9768 100644
@@ -186,7 +186,7 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
 	 */
 	if (dev->vendor == 0x1959 && dev->device == 0xa007 &&
 	    !firmware_has_feature(FW_FEATURE_LPAR)) {
-		dev->dev.dma_ops = &dma_direct_ops;
+		dev->dev.dma_ops = &dma_nommu_ops;
 		/*
 		 * Set the coherent DMA mask to prevent the iommu
 		 * being used unnecessarily
arch/powerpc/platforms/pasemi/setup.c +1 -1
index c4a3e93dc324..d0b8ae53660d 100644
@@ -363,7 +363,7 @@ static int pcmcia_notify(struct notifier_block *nb, unsigned long action,
 		return 0;
 
 	/* We use the direct ops for localbus */
-	dev->dma_ops = &dma_direct_ops;
+	dev->dma_ops = &dma_nommu_ops;
 
 	return 0;
 }
arch/powerpc/platforms/powernv/pci-ioda.c +2 -2
index 749055553064..9582aeb1fe4c 100644
@@ -1850,7 +1850,7 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
 
 	if (bypass) {
 		dev_info(&pdev->dev, "Using 64-bit DMA iommu bypass\n");
-		set_dma_ops(&pdev->dev, &dma_direct_ops);
+		set_dma_ops(&pdev->dev, &dma_nommu_ops);
 	} else {
 		/*
 		 * If the device can't set the TCE bypass bit but still wants
@@ -1868,7 +1868,7 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
 				return rc;
 			/* 4GB offset bypasses 32-bit space */
 			set_dma_offset(&pdev->dev, (1ULL << 32));
-			set_dma_ops(&pdev->dev, &dma_direct_ops);
+			set_dma_ops(&pdev->dev, &dma_nommu_ops);
 		} else if (dma_mask >> 32 && dma_mask != DMA_BIT_MASK(64)) {
 			/*
 			 * Fail the request if a DMA mask between 32 and 64 bits
arch/powerpc/platforms/pseries/iommu.c +1 -1
index 69921f72e2da..eaa11334fc8c 100644
@@ -1231,7 +1231,7 @@ static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)
 			if (dma_offset != 0) {
 				dev_info(dev, "Using 64-bit direct DMA at offset %llx\n", dma_offset);
 				set_dma_offset(dev, dma_offset);
-				set_dma_ops(dev, &dma_direct_ops);
+				set_dma_ops(dev, &dma_nommu_ops);
 				ddw_enabled = true;
 			}
 		}
arch/powerpc/platforms/pseries/vio.c +1 -1
index d86938260a86..49e04ec19238 100644
@@ -618,7 +618,7 @@ static u64 vio_dma_get_required_mask(struct device *dev)
 static const struct dma_map_ops vio_dma_mapping_ops = {
 	.alloc             = vio_dma_iommu_alloc_coherent,
 	.free              = vio_dma_iommu_free_coherent,
-	.mmap		   = dma_direct_mmap_coherent,
+	.mmap		   = dma_nommu_mmap_coherent,
 	.map_sg            = vio_dma_iommu_map_sg,
 	.unmap_sg          = vio_dma_iommu_unmap_sg,
 	.map_page          = vio_dma_iommu_map_page,
arch/powerpc/sysdev/dart_iommu.c +2 -2
index 3573d54b2770..a6198d4f0f03 100644
@@ -402,7 +402,7 @@ static int dart_dma_set_mask(struct device *dev, u64 dma_mask)
 	 */
 	if (dart_device_on_pcie(dev) && dma_mask >= DMA_BIT_MASK(40)) {
 		dev_info(dev, "Using 64-bit DMA iommu bypass\n");
-		set_dma_ops(dev, &dma_direct_ops);
+		set_dma_ops(dev, &dma_nommu_ops);
 	} else {
 		dev_info(dev, "Using 32-bit DMA via iommu\n");
 		set_dma_ops(dev, &dma_iommu_ops);
@@ -446,7 +446,7 @@ void __init iommu_init_early_dart(struct pci_controller_ops *controller_ops)
 	controller_ops->dma_bus_setup = NULL;
 
 	/* Setup pci_dma ops */
-	set_pci_dma_ops(&dma_direct_ops);
+	set_pci_dma_ops(&dma_nommu_ops);
 }
 
 #ifdef CONFIG_PM
arch/powerpc/sysdev/fsl_pci.c +1 -1
index 22d98057f773..e4d0133bbeeb 100644
@@ -135,7 +135,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 	 * mapping that allows addressing any RAM address from across PCI.
 	 */
 	if (dev_is_pci(dev) && dma_mask >= pci64_dma_offset * 2 - 1) {
-		set_dma_ops(dev, &dma_direct_ops);
+		set_dma_ops(dev, &dma_nommu_ops);
 		set_dma_offset(dev, pci64_dma_offset);
 	}
 
drivers/misc/cxl/vphb.c +1 -1
index 512a4897dbf6..7fd0bdc1436a 100644
@@ -54,7 +54,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
 		return false;
 	}
 
-	set_dma_ops(&dev->dev, &dma_direct_ops);
+	set_dma_ops(&dev->dev, &dma_nommu_ops);
 	set_dma_offset(&dev->dev, PAGE_OFFSET);
 
 	return _cxl_pci_associate_default_context(dev, afu);
Signature · 1 line
2.14.2
#56 lore raw

PATCH 17/67 microblaze: rename dma_direct to dma_microblaze

In reply to Christoph Hellwig

This frees the dma_direct_* namespace for a generic implementation.

---
 arch/microblaze/include/asm/dma-mapping.h |  4 +--
 arch/microblaze/kernel/dma.c              | 50 +++++++++++++++----------------
 2 files changed, 27 insertions(+), 27 deletions(-)
arch/microblaze/include/asm/dma-mapping.h +2 -2
index 6b9ea39405b8..add50c1373bf 100644
@@ -18,11 +18,11 @@
 /*
  * Available generic sets of operations
  */
-extern const struct dma_map_ops dma_direct_ops;
+extern const struct dma_map_ops dma_nommu_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-	return &dma_direct_ops;
+	return &dma_nommu_ops;
 }
 
 #endif	/* _ASM_MICROBLAZE_DMA_MAPPING_H */
arch/microblaze/kernel/dma.c +25 -25

121 lines not on this page · raw message

Signature · 1 line
2.14.2
#57 lore raw

Re: [PATCH 17/67] microblaze: rename dma_direct to dma_microblaze

Hi Christoph,

Quoted 1 line · Christoph Hellwig

This frees the dma_direct_* namespace for a generic implementation.

Don't you mean "dma_nommu" not "dma_microblaze" in the subject line?

Thanks,

Signature · 4 lines
Julian Calaby

Email: [email protected]
Profile: http://www.google.com/profiles/julian.calaby/
#58 lore raw

Re: [PATCH 17/67] microblaze: rename dma_direct to dma_microblaze

Quoted 6 lines · Julian Calaby

Hi Christoph,

Quoted 1 line · Christoph Hellwig

This frees the dma_direct_* namespace for a generic implementation.

Don't you mean "dma_nommu" not "dma_microblaze" in the subject line?

Yes, thanks.

#59 lore raw

PATCH 18/67 microblaze: remove dma_nommu_dma_supported

In reply to Christoph Hellwig

Always returning 1 is the same behavior as not supplying a method at all.

---
 arch/microblaze/kernel/dma.c | 6 ------
 arch/parisc/kernel/pci-dma.c | 7 -------
 2 files changed, 13 deletions(-)
arch/microblaze/kernel/dma.c +0 -6
index 364b0ac41452..49b09648679b 100644
@@ -89,11 +89,6 @@ static int dma_nommu_map_sg(struct device *dev, struct scatterlist *sgl,
 	return nents;
 }
 
-static int dma_nommu_dma_supported(struct device *dev, u64 mask)
-{
-	return 1;
-}
-
 static inline dma_addr_t dma_nommu_map_page(struct device *dev,
 					     struct page *page,
 					     unsigned long offset,
@@ -209,7 +204,6 @@ const struct dma_map_ops dma_nommu_ops = {
 	.free			= dma_nommu_free_coherent,
 	.mmap			= dma_nommu_mmap_coherent,
 	.map_sg			= dma_nommu_map_sg,
-	.dma_supported		= dma_nommu_dma_supported,
 	.map_page		= dma_nommu_map_page,
 	.unmap_page		= dma_nommu_unmap_page,
 	.sync_single_for_cpu	= dma_nommu_sync_single_for_cpu,
arch/parisc/kernel/pci-dma.c +0 -7
index 6ad9aed3d025..2a05457f7aab 100644
@@ -75,11 +75,6 @@ void dump_resmap(void)
 static inline void dump_resmap(void) {;}
 #endif
 
-static int pa11_dma_supported( struct device *dev, u64 mask)
-{
-	return 1;
-}
-
 static inline int map_pte_uncached(pte_t * pte,
 		unsigned long vaddr,
 		unsigned long size, unsigned long *paddr_ptr)
@@ -579,7 +574,6 @@ static void pa11_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 }
 
 const struct dma_map_ops pcxl_dma_ops = {
-	.dma_supported =	pa11_dma_supported,
 	.alloc =		pa11_dma_alloc,
 	.free =			pa11_dma_free,
 	.map_page =		pa11_dma_map_page,
@@ -617,7 +611,6 @@ static void pcx_dma_free(struct device *dev, size_t size, void *vaddr,
 }
 
 const struct dma_map_ops pcx_dma_ops = {
-	.dma_supported =	pa11_dma_supported,
 	.alloc =		pcx_dma_alloc,
 	.free =			pcx_dma_free,
 	.map_page =		pa11_dma_map_page,
Signature · 1 line
2.14.2
#60 lore raw

PATCH 18/67 microblaze: remove dma_nommu_dma_supported

In reply to Christoph Hellwig

Always returning 1 is the same behavior as not supplying a method at all.

---
 arch/microblaze/kernel/dma.c | 6 ------
 arch/parisc/kernel/pci-dma.c | 7 -------
 2 files changed, 13 deletions(-)
arch/microblaze/kernel/dma.c +0 -6
index 364b0ac41452..49b09648679b 100644
@@ -89,11 +89,6 @@ static int dma_nommu_map_sg(struct device *dev, struct scatterlist *sgl,
 	return nents;
 }
 
-static int dma_nommu_dma_supported(struct device *dev, u64 mask)
-{
-	return 1;
-}
-
 static inline dma_addr_t dma_nommu_map_page(struct device *dev,
 					     struct page *page,
 					     unsigned long offset,
@@ -209,7 +204,6 @@ const struct dma_map_ops dma_nommu_ops = {
 	.free			= dma_nommu_free_coherent,
 	.mmap			= dma_nommu_mmap_coherent,
 	.map_sg			= dma_nommu_map_sg,
-	.dma_supported		= dma_nommu_dma_supported,
 	.map_page		= dma_nommu_map_page,
 	.unmap_page		= dma_nommu_unmap_page,
 	.sync_single_for_cpu	= dma_nommu_sync_single_for_cpu,
arch/parisc/kernel/pci-dma.c +0 -7
index 6ad9aed3d025..2a05457f7aab 100644
@@ -75,11 +75,6 @@ void dump_resmap(void)
 static inline void dump_resmap(void) {;}
 #endif
 
-static int pa11_dma_supported( struct device *dev, u64 mask)
-{
-	return 1;
-}
-
 static inline int map_pte_uncached(pte_t * pte,
 		unsigned long vaddr,
 		unsigned long size, unsigned long *paddr_ptr)
@@ -579,7 +574,6 @@ static void pa11_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 }
 
 const struct dma_map_ops pcxl_dma_ops = {
-	.dma_supported =	pa11_dma_supported,
 	.alloc =		pa11_dma_alloc,
 	.free =			pa11_dma_free,
 	.map_page =		pa11_dma_map_page,
@@ -617,7 +611,6 @@ static void pcx_dma_free(struct device *dev, size_t size, void *vaddr,
 }
 
 const struct dma_map_ops pcx_dma_ops = {
-	.dma_supported =	pa11_dma_supported,
 	.alloc =		pcx_dma_alloc,
 	.free =			pcx_dma_free,
 	.map_page =		pa11_dma_map_page,
Signature · 1 line
2.14.2
#61 lore raw

PATCH 19/67 microblaze: remove the dead !NOT_COHERENT_CACHE dma code

In reply to Christoph Hellwig
---
 arch/microblaze/kernel/dma.c | 28 ----------------------------
 1 file changed, 28 deletions(-)
arch/microblaze/kernel/dma.c +0 -28
index 49b09648679b..031d889670f5 100644
@@ -15,42 +15,18 @@
 #include <linux/bug.h>
 #include <asm/cacheflush.h>
 
-#define NOT_COHERENT_CACHE
-
 static void *dma_nommu_alloc_coherent(struct device *dev, size_t size,
 				       dma_addr_t *dma_handle, gfp_t flag,
 				       unsigned long attrs)
 {
-#ifdef NOT_COHERENT_CACHE
 	return consistent_alloc(flag, size, dma_handle);
-#else
-	void *ret;
-	struct page *page;
-	int node = dev_to_node(dev);
-
-	/* ignore region specifiers */
-	flag  &= ~(__GFP_HIGHMEM);
-
-	page = alloc_pages_node(node, flag, get_order(size));
-	if (page == NULL)
-		return NULL;
-	ret = page_address(page);
-	memset(ret, 0, size);
-	*dma_handle = virt_to_phys(ret);
-
-	return ret;
-#endif
 }
 
 static void dma_nommu_free_coherent(struct device *dev, size_t size,
 				     void *vaddr, dma_addr_t dma_handle,
 				     unsigned long attrs)
 {
-#ifdef NOT_COHERENT_CACHE
 	consistent_free(size, vaddr);
-#else
-	free_pages((unsigned long)vaddr, get_order(size));
-#endif
 }
 
 static inline void __dma_sync(unsigned long paddr,
@@ -186,12 +162,8 @@ int dma_nommu_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
 	if (off >= count || user_count > (count - off))
 		return -ENXIO;
 
-#ifdef NOT_COHERENT_CACHE
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 	pfn = consistent_virt_to_pfn(cpu_addr);
-#else
-	pfn = virt_to_pfn(cpu_addr);
-#endif
 	return remap_pfn_range(vma, vma->vm_start, pfn + off,
 			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
 #else
Signature · 1 line
2.14.2
#62 lore raw

PATCH 19/67 microblaze: remove the dead !NOT_COHERENT_CACHE dma code

In reply to Christoph Hellwig
---
 arch/microblaze/kernel/dma.c | 28 ----------------------------
 1 file changed, 28 deletions(-)
arch/microblaze/kernel/dma.c +0 -28
index 49b09648679b..031d889670f5 100644
@@ -15,42 +15,18 @@
 #include <linux/bug.h>
 #include <asm/cacheflush.h>
 
-#define NOT_COHERENT_CACHE
-
 static void *dma_nommu_alloc_coherent(struct device *dev, size_t size,
 				       dma_addr_t *dma_handle, gfp_t flag,
 				       unsigned long attrs)
 {
-#ifdef NOT_COHERENT_CACHE
 	return consistent_alloc(flag, size, dma_handle);
-#else
-	void *ret;
-	struct page *page;
-	int node = dev_to_node(dev);
-
-	/* ignore region specifiers */
-	flag  &= ~(__GFP_HIGHMEM);
-
-	page = alloc_pages_node(node, flag, get_order(size));
-	if (page == NULL)
-		return NULL;
-	ret = page_address(page);
-	memset(ret, 0, size);
-	*dma_handle = virt_to_phys(ret);
-
-	return ret;
-#endif
 }
 
 static void dma_nommu_free_coherent(struct device *dev, size_t size,
 				     void *vaddr, dma_addr_t dma_handle,
 				     unsigned long attrs)
 {
-#ifdef NOT_COHERENT_CACHE
 	consistent_free(size, vaddr);
-#else
-	free_pages((unsigned long)vaddr, get_order(size));
-#endif
 }
 
 static inline void __dma_sync(unsigned long paddr,
@@ -186,12 +162,8 @@ int dma_nommu_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
 	if (off >= count || user_count > (count - off))
 		return -ENXIO;
 
-#ifdef NOT_COHERENT_CACHE
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 	pfn = consistent_virt_to_pfn(cpu_addr);
-#else
-	pfn = virt_to_pfn(cpu_addr);
-#endif
 	return remap_pfn_range(vma, vma->vm_start, pfn + off,
 			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
 #else
Signature · 1 line
2.14.2
#63 lore raw

PATCH 20/67 s390: move s390_pci_dma_ops to asm/pci_dma.h

In reply to Christoph Hellwig

This is not needed in drivers, so move it to a private header.

---
 arch/s390/include/asm/dma-mapping.h | 2 --
 arch/s390/include/asm/pci_dma.h     | 3 +++
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/s390/include/asm/dma-mapping.h +0 -2
index 2ec7240c1ada..bdc2455483f6 100644
@@ -9,8 +9,6 @@
 #include <linux/dma-debug.h>
 #include <linux/io.h>
 
-extern const struct dma_map_ops s390_pci_dma_ops;
-
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
 	return &dma_noop_ops;
arch/s390/include/asm/pci_dma.h +3 -0
index e8d9161fa17a..419fac7a62c0 100644
@@ -201,4 +201,7 @@ void dma_cleanup_tables(unsigned long *);
 unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr);
 void dma_update_cpu_trans(unsigned long *entry, void *page_addr, int flags);
 
+extern const struct dma_map_ops s390_pci_dma_ops;
+
+
 #endif
Signature · 1 line
2.14.2
#64 lore raw

PATCH 20/67 s390: move s390_pci_dma_ops to asm/pci_dma.h

In reply to Christoph Hellwig

This is not needed in drivers, so move it to a private header.

---
 arch/s390/include/asm/dma-mapping.h | 2 --
 arch/s390/include/asm/pci_dma.h     | 3 +++
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/s390/include/asm/dma-mapping.h +0 -2
index 2ec7240c1ada..bdc2455483f6 100644
@@ -9,8 +9,6 @@
 #include <linux/dma-debug.h>
 #include <linux/io.h>
 
-extern const struct dma_map_ops s390_pci_dma_ops;
-
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
 	return &dma_noop_ops;
arch/s390/include/asm/pci_dma.h +3 -0
index e8d9161fa17a..419fac7a62c0 100644
@@ -201,4 +201,7 @@ void dma_cleanup_tables(unsigned long *);
 unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr);
 void dma_update_cpu_trans(unsigned long *entry, void *page_addr, int flags);
 
+extern const struct dma_map_ops s390_pci_dma_ops;
+
+
 #endif
Signature · 1 line
2.14.2
#65 lore raw

PATCH 21/67 dma-mapping: warn when there is no coherent_dma_mask

In reply to Christoph Hellwig

These days all devices should have a DMA coherent mask, and most dma_ops implementations rely on that fact. But just to be sure add an assert to ring the warning bell if that is not the case.

---
 include/linux/dma-mapping.h | 1 +
 1 file changed, 1 insertion(+)
include/linux/dma-mapping.h +1 -0
index e77e2dec4723..2779d544485c 100644
@@ -520,6 +520,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 	void *cpu_addr;
 
 	BUG_ON(!ops);
+	WARN_ON_ONCE(!dev->coherent_dma_mask);
 
 	if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
 		return cpu_addr;
Signature · 1 line
2.14.2
#66 lore raw

PATCH 21/67 dma-mapping: warn when there is no coherent_dma_mask

In reply to Christoph Hellwig

These days all devices should have a DMA coherent mask, and most dma_ops implementations rely on that fact. But just to be sure add an assert to ring the warning bell if that is not the case.

---
 include/linux/dma-mapping.h | 1 +
 1 file changed, 1 insertion(+)
include/linux/dma-mapping.h +1 -0
index e77e2dec4723..2779d544485c 100644
@@ -520,6 +520,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 	void *cpu_addr;
 
 	BUG_ON(!ops);
+	WARN_ON_ONCE(!dev->coherent_dma_mask);
 
 	if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
 		return cpu_addr;
Signature · 1 line
2.14.2
#67 lore raw

PATCH 22/67 dma-mapping: clear harmful GFP_* flags in common code

In reply to Christoph Hellwig

Life the code from x86 so that we behave consistently. In the future we should probably warn if any of these is set.

---
 arch/cris/arch-v32/drivers/pci/dma.c      | 3 ---
 arch/h8300/kernel/dma.c                   | 3 ---
 arch/m68k/kernel/dma.c                    | 2 --
 arch/mips/cavium-octeon/dma-octeon.c      | 3 ---
 arch/mips/loongson64/common/dma-swiotlb.c | 3 ---
 arch/mips/mm/dma-default.c                | 3 ---
 arch/mips/netlogic/common/nlm-dma.c       | 3 ---
 arch/mn10300/mm/dma-alloc.c               | 3 ---
 arch/nios2/mm/dma-mapping.c               | 3 ---
 arch/powerpc/kernel/dma.c                 | 3 ---
 arch/x86/kernel/pci-dma.c                 | 2 --
 include/linux/dma-mapping.h               | 7 +++++++
 12 files changed, 7 insertions(+), 31 deletions(-)
arch/cris/arch-v32/drivers/pci/dma.c +0 -3
index aa16ce27e036..c7e3056885d3 100644
@@ -22,9 +22,6 @@ static void *v32_dma_alloc(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
 	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
 
arch/h8300/kernel/dma.c +0 -3
index 0e92214310c4..4e27b74df973 100644
@@ -16,9 +16,6 @@ static void *dma_alloc(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
 	if (dev == NULL || (*dev->dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
 	ret = (void *)__get_free_pages(gfp, get_order(size));
arch/m68k/kernel/dma.c +0 -2
index e0167418072b..2f3492e8295c 100644
@@ -76,8 +76,6 @@ static void *m68k_dma_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
 	void *ret;
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
 
 	if (dev == NULL || (*dev->dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
arch/mips/cavium-octeon/dma-octeon.c +0 -3
index c64bd87f0b6e..5baf79fce643 100644
@@ -161,9 +161,6 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-
 	if (IS_ENABLED(CONFIG_ZONE_DMA) && dev == NULL)
 		gfp |= __GFP_DMA;
 	else if (IS_ENABLED(CONFIG_ZONE_DMA) &&
arch/mips/loongson64/common/dma-swiotlb.c +0 -3
index ef07740cee61..15388c24a504 100644
@@ -15,9 +15,6 @@ static void *loongson_dma_alloc_coherent(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-
 	if ((IS_ENABLED(CONFIG_ISA) && dev == NULL) ||
 	    (IS_ENABLED(CONFIG_ZONE_DMA) &&
 	     dev->coherent_dma_mask < DMA_BIT_MASK(32)))
arch/mips/mm/dma-default.c +0 -3
index 3cd93e0c7a29..6f6b1399e98e 100644
@@ -93,9 +93,6 @@ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
 {
 	gfp_t dma_flag;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-
 #ifdef CONFIG_ISA
 	if (dev == NULL)
 		dma_flag = __GFP_DMA;
arch/mips/netlogic/common/nlm-dma.c +0 -3
index 0ec9d9da6d51..49c975b6aa28 100644
@@ -47,9 +47,6 @@ static char *nlm_swiotlb;
 static void *nlm_dma_alloc_coherent(struct device *dev, size_t size,
 	dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-
 #ifdef CONFIG_ZONE_DMA32
 	if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
 		gfp |= __GFP_DMA32;
arch/mn10300/mm/dma-alloc.c +0 -3
index 55876a87c247..2629f1f4b04e 100644
@@ -37,9 +37,6 @@ static void *mn10300_dma_alloc(struct device *dev, size_t size,
 		goto done;
 	}
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
 	if (dev == NULL || dev->coherent_dma_mask < 0xffffffff)
 		gfp |= GFP_DMA;
 
arch/nios2/mm/dma-mapping.c +0 -3
index 599bcc09c9e7..9e54f8cb3459 100644
@@ -63,9 +63,6 @@ static void *nios2_dma_alloc(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
 	/* optimized page clearing */
 	gfp |= __GFP_ZERO;
 
arch/powerpc/kernel/dma.c +0 -3
index 5d49da094a93..1723001d5de1 100644
@@ -105,9 +105,6 @@ void *__dma_nommu_alloc_coherent(struct device *dev, size_t size,
 	};
 #endif /* CONFIG_FSL_SOC */
 
-	/* ignore region specifiers */
-	flag  &= ~(__GFP_HIGHMEM);
-
 	page = alloc_pages_node(node, flag, get_order(size));
 	if (page == NULL)
 		return NULL;
arch/x86/kernel/pci-dma.c +0 -2
index 8439e6de6156..61a8f1cb3829 100644
@@ -87,7 +87,6 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 
 	dma_mask = dma_alloc_coherent_mask(dev, flag);
 
-	flag &= ~__GFP_ZERO;
 again:
 	page = NULL;
 	/* CMA can be used only in the context which permits sleeping */
@@ -139,7 +138,6 @@ bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp)
 	if (!*dev)
 		*dev = &x86_dma_fallback_dev;
 
-	*gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
 	*gfp = dma_alloc_coherent_gfp_flags(*dev, *gfp);
 
 	if (!is_device_dma_capable(*dev))
include/linux/dma-mapping.h +7 -0
index 2779d544485c..fd5197af882a 100644
@@ -525,6 +525,13 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 	if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
 		return cpu_addr;
 
+	/*
+	 * Let the implementation decide on the zone to allocate from, and
+	 * decide on the way of zeroing the memory given that the memory
+	 * returned should always be zeroed.
+	 */
+	flag &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM | __GFP_ZERO);
+
 	if (!arch_dma_alloc_attrs(&dev, &flag))
 		return NULL;
 	if (!ops->alloc)
Signature · 1 line
2.14.2
maintainer Acked-by on v1 22/67
#68 lore raw

Re: [PATCH 22/67] dma-mapping: clear harmful GFP_* flags in common code

Quoted 4 lines · Christoph Hellwig

Life the code from x86 so that we behave consistently. In the future we should probably warn if any of these is set.

For m68k:

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

Acked-by on v1 22/67
#69 lore raw

Re: [PATCH 22/67] dma-mapping: clear harmful GFP_* flags in common code

In reply to Christoph Hellwig
Quoted 4 lines · Christoph Hellwig

Life the code from x86 so that we behave consistently. In the future we should probably warn if any of these is set.

Quoted 2 lines
---
 arch/cris/arch-v32/drivers/pci/dma.c      | 3 ---

/^JN - Jesper Nilsson

Signature · 1 line
               Jesper Nilsson -- [email protected]
#70 lore raw

PATCH 22/67 dma-mapping: clear harmful GFP_* flags in common code

In reply to Christoph Hellwig

Life the code from x86 so that we behave consistently. In the future we should probably warn if any of these is set.

---
 arch/cris/arch-v32/drivers/pci/dma.c      | 3 ---
 arch/h8300/kernel/dma.c                   | 3 ---
 arch/m68k/kernel/dma.c                    | 2 --
 arch/mips/cavium-octeon/dma-octeon.c      | 3 ---
 arch/mips/loongson64/common/dma-swiotlb.c | 3 ---
 arch/mips/mm/dma-default.c                | 3 ---
 arch/mips/netlogic/common/nlm-dma.c       | 3 ---
 arch/mn10300/mm/dma-alloc.c               | 3 ---
 arch/nios2/mm/dma-mapping.c               | 3 ---
 arch/powerpc/kernel/dma.c                 | 3 ---
 arch/x86/kernel/pci-dma.c                 | 2 --
 include/linux/dma-mapping.h               | 7 +++++++
 12 files changed, 7 insertions(+), 31 deletions(-)
arch/cris/arch-v32/drivers/pci/dma.c +0 -3
index aa16ce27e036..c7e3056885d3 100644
@@ -22,9 +22,6 @@ static void *v32_dma_alloc(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
 	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
 
arch/h8300/kernel/dma.c +0 -3
index 0e92214310c4..4e27b74df973 100644
@@ -16,9 +16,6 @@ static void *dma_alloc(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
 	if (dev == NULL || (*dev->dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
 	ret = (void *)__get_free_pages(gfp, get_order(size));
arch/m68k/kernel/dma.c +0 -2
index e0167418072b..2f3492e8295c 100644
@@ -76,8 +76,6 @@ static void *m68k_dma_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
 	void *ret;
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
 
 	if (dev == NULL || (*dev->dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
arch/mips/cavium-octeon/dma-octeon.c +0 -3
index c64bd87f0b6e..5baf79fce643 100644
@@ -161,9 +161,6 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-
 	if (IS_ENABLED(CONFIG_ZONE_DMA) && dev == NULL)
 		gfp |= __GFP_DMA;
 	else if (IS_ENABLED(CONFIG_ZONE_DMA) &&
arch/mips/loongson64/common/dma-swiotlb.c +0 -3
index ef07740cee61..15388c24a504 100644
@@ -15,9 +15,6 @@ static void *loongson_dma_alloc_coherent(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-
 	if ((IS_ENABLED(CONFIG_ISA) && dev == NULL) ||
 	    (IS_ENABLED(CONFIG_ZONE_DMA) &&
 	     dev->coherent_dma_mask < DMA_BIT_MASK(32)))
arch/mips/mm/dma-default.c +0 -3
index 3cd93e0c7a29..6f6b1399e98e 100644
@@ -93,9 +93,6 @@ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
 {
 	gfp_t dma_flag;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-
 #ifdef CONFIG_ISA
 	if (dev == NULL)
 		dma_flag = __GFP_DMA;
arch/mips/netlogic/common/nlm-dma.c +0 -3
index 0ec9d9da6d51..49c975b6aa28 100644
@@ -47,9 +47,6 @@ static char *nlm_swiotlb;
 static void *nlm_dma_alloc_coherent(struct device *dev, size_t size,
 	dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
-
 #ifdef CONFIG_ZONE_DMA32
 	if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
 		gfp |= __GFP_DMA32;
arch/mn10300/mm/dma-alloc.c +0 -3
index 55876a87c247..2629f1f4b04e 100644
@@ -37,9 +37,6 @@ static void *mn10300_dma_alloc(struct device *dev, size_t size,
 		goto done;
 	}
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
 	if (dev == NULL || dev->coherent_dma_mask < 0xffffffff)
 		gfp |= GFP_DMA;
 
arch/nios2/mm/dma-mapping.c +0 -3
index 599bcc09c9e7..9e54f8cb3459 100644
@@ -63,9 +63,6 @@ static void *nios2_dma_alloc(struct device *dev, size_t size,
 {
 	void *ret;
 
-	/* ignore region specifiers */
-	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
 	/* optimized page clearing */
 	gfp |= __GFP_ZERO;
 
arch/powerpc/kernel/dma.c +0 -3
index 5d49da094a93..1723001d5de1 100644
@@ -105,9 +105,6 @@ void *__dma_nommu_alloc_coherent(struct device *dev, size_t size,
 	};
 #endif /* CONFIG_FSL_SOC */
 
-	/* ignore region specifiers */
-	flag  &= ~(__GFP_HIGHMEM);
-
 	page = alloc_pages_node(node, flag, get_order(size));
 	if (page == NULL)
 		return NULL;
arch/x86/kernel/pci-dma.c +0 -2
index 8439e6de6156..61a8f1cb3829 100644
@@ -87,7 +87,6 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 
 	dma_mask = dma_alloc_coherent_mask(dev, flag);
 
-	flag &= ~__GFP_ZERO;
 again:
 	page = NULL;
 	/* CMA can be used only in the context which permits sleeping */
@@ -139,7 +138,6 @@ bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp)
 	if (!*dev)
 		*dev = &x86_dma_fallback_dev;
 
-	*gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
 	*gfp = dma_alloc_coherent_gfp_flags(*dev, *gfp);
 
 	if (!is_device_dma_capable(*dev))
include/linux/dma-mapping.h +7 -0
index 2779d544485c..fd5197af882a 100644
@@ -525,6 +525,13 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 	if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
 		return cpu_addr;
 
+	/*
+	 * Let the implementation decide on the zone to allocate from, and
+	 * decide on the way of zeroing the memory given that the memory
+	 * returned should always be zeroed.
+	 */
+	flag &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM | __GFP_ZERO);
+
 	if (!arch_dma_alloc_attrs(&dev, &flag))
 		return NULL;
 	if (!ops->alloc)
Signature · 1 line
2.14.2
#71 lore raw

PATCH 23/67 dma-mapping: add an arch_dma_supported hook

In reply to Christoph Hellwig

To implement the x86 forbid_dac and iommu_sac_force we want an arch hook so that it can apply the global options across all dma_map_ops implementations.

---
 arch/x86/include/asm/dma-mapping.h |  3 +++
 arch/x86/kernel/pci-dma.c          | 19 ++++++++++++-------
 include/linux/dma-mapping.h        | 11 +++++++++++
 3 files changed, 26 insertions(+), 7 deletions(-)
arch/x86/include/asm/dma-mapping.h +3 -0
index dfdc9357a349..6277c83c0eb1 100644
@@ -30,6 +30,9 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return dma_ops;
 }
 
+int arch_dma_supported(struct device *dev, u64 mask);
+#define arch_dma_supported arch_dma_supported
+
 bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp);
 #define arch_dma_alloc_attrs arch_dma_alloc_attrs
 
arch/x86/kernel/pci-dma.c +12 -7
index 61a8f1cb3829..df7ab02f959f 100644
@@ -215,7 +215,7 @@ static __init int iommu_setup(char *p)
 }
 early_param("iommu", iommu_setup);
 
-int x86_dma_supported(struct device *dev, u64 mask)
+int arch_dma_supported(struct device *dev, u64 mask)
 {
 #ifdef CONFIG_PCI
 	if (mask > 0xffffffff && forbid_dac > 0) {
@@ -224,12 +224,6 @@ int x86_dma_supported(struct device *dev, u64 mask)
 	}
 #endif
 
-	/* Copied from i386. Doesn't make much sense, because it will
-	   only work for pci_alloc_coherent.
-	   The caller just has to use GFP_DMA in this case. */
-	if (mask < DMA_BIT_MASK(24))
-		return 0;
-
 	/* Tell the device to use SAC when IOMMU force is on.  This
 	   allows the driver to use cheaper accesses in some cases.
 
@@ -249,6 +243,17 @@ int x86_dma_supported(struct device *dev, u64 mask)
 
 	return 1;
 }
+EXPORT_SYMBOL(arch_dma_supported);
+
+int x86_dma_supported(struct device *dev, u64 mask)
+{
+	/* Copied from i386. Doesn't make much sense, because it will
+	   only work for pci_alloc_coherent.
+	   The caller just has to use GFP_DMA in this case. */
+	if (mask < DMA_BIT_MASK(24))
+		return 0;
+	return 1;
+}
 
 static int __init pci_iommu_init(void)
 {
include/linux/dma-mapping.h +11 -0
index fd5197af882a..72568bf4fc12 100644
@@ -583,6 +583,14 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 	return 0;
 }
 
+/*
+ * This is a hack for the legacy x86 forbid_dac and iommu_sac_force. Please
+ * don't use this is new code.
+ */
+#ifndef arch_dma_supported
+#define arch_dma_supported(dev, mask)	(1)
+#endif
+
 static inline void dma_check_mask(struct device *dev, u64 mask)
 {
 	if (sme_active() && (mask < (((u64)sme_get_me_mask() << 1) - 1)))
@@ -595,6 +603,9 @@ static inline int dma_supported(struct device *dev, u64 mask)
 
 	if (!ops)
 		return 0;
+	if (!arch_dma_supported(dev, mask))
+		return 0;
+
 	if (!ops->dma_supported)
 		return 1;
 	return ops->dma_supported(dev, mask);
Signature · 1 line
2.14.2
#72 lore raw

PATCH 23/67 dma-mapping: add an arch_dma_supported hook

In reply to Christoph Hellwig

To implement the x86 forbid_dac and iommu_sac_force we want an arch hook so that it can apply the global options across all dma_map_ops implementations.

---
 arch/x86/include/asm/dma-mapping.h |  3 +++
 arch/x86/kernel/pci-dma.c          | 19 ++++++++++++-------
 include/linux/dma-mapping.h        | 11 +++++++++++
 3 files changed, 26 insertions(+), 7 deletions(-)
arch/x86/include/asm/dma-mapping.h +3 -0
index dfdc9357a349..6277c83c0eb1 100644
@@ -30,6 +30,9 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 	return dma_ops;
 }
 
+int arch_dma_supported(struct device *dev, u64 mask);
+#define arch_dma_supported arch_dma_supported
+
 bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp);
 #define arch_dma_alloc_attrs arch_dma_alloc_attrs
 
arch/x86/kernel/pci-dma.c +12 -7
index 61a8f1cb3829..df7ab02f959f 100644
@@ -215,7 +215,7 @@ static __init int iommu_setup(char *p)
 }
 early_param("iommu", iommu_setup);
 
-int x86_dma_supported(struct device *dev, u64 mask)
+int arch_dma_supported(struct device *dev, u64 mask)
 {
 #ifdef CONFIG_PCI
 	if (mask > 0xffffffff && forbid_dac > 0) {
@@ -224,12 +224,6 @@ int x86_dma_supported(struct device *dev, u64 mask)
 	}
 #endif
 
-	/* Copied from i386. Doesn't make much sense, because it will
-	   only work for pci_alloc_coherent.
-	   The caller just has to use GFP_DMA in this case. */
-	if (mask < DMA_BIT_MASK(24))
-		return 0;
-
 	/* Tell the device to use SAC when IOMMU force is on.  This
 	   allows the driver to use cheaper accesses in some cases.
 
@@ -249,6 +243,17 @@ int x86_dma_supported(struct device *dev, u64 mask)
 
 	return 1;
 }
+EXPORT_SYMBOL(arch_dma_supported);
+
+int x86_dma_supported(struct device *dev, u64 mask)
+{
+	/* Copied from i386. Doesn't make much sense, because it will
+	   only work for pci_alloc_coherent.
+	   The caller just has to use GFP_DMA in this case. */
+	if (mask < DMA_BIT_MASK(24))
+		return 0;
+	return 1;
+}
 
 static int __init pci_iommu_init(void)
 {
include/linux/dma-mapping.h +11 -0
index fd5197af882a..72568bf4fc12 100644
@@ -583,6 +583,14 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 	return 0;
 }
 
+/*
+ * This is a hack for the legacy x86 forbid_dac and iommu_sac_force. Please
+ * don't use this is new code.
+ */
+#ifndef arch_dma_supported
+#define arch_dma_supported(dev, mask)	(1)
+#endif
+
 static inline void dma_check_mask(struct device *dev, u64 mask)
 {
 	if (sme_active() && (mask < (((u64)sme_get_me_mask() << 1) - 1)))
@@ -595,6 +603,9 @@ static inline int dma_supported(struct device *dev, u64 mask)
 
 	if (!ops)
 		return 0;
+	if (!arch_dma_supported(dev, mask))
+		return 0;
+
 	if (!ops->dma_supported)
 		return 1;
 	return ops->dma_supported(dev, mask);
Signature · 1 line
2.14.2
#73 lore raw

PATCH 24/67 dma-mapping: provide a generic asm/dma-mapping.h

In reply to Christoph Hellwig

For architectures that just use the generic dma_noop_ops we can provide a generic version of dma-mapping.h.

---
 MAINTAINERS                          |  1 +
 arch/m32r/include/asm/Kbuild         |  1 +
 arch/m32r/include/asm/dma-mapping.h  | 17 -----------------
 arch/riscv/include/asm/Kbuild        |  1 +
 arch/riscv/include/asm/dma-mapping.h | 30 ------------------------------
 arch/s390/include/asm/Kbuild         |  1 +
 arch/s390/include/asm/dma-mapping.h  | 17 -----------------
 include/asm-generic/dma-mapping.h    | 10 ++++++++++
 8 files changed, 14 insertions(+), 64 deletions(-)
 delete mode 100644 arch/m32r/include/asm/dma-mapping.h
 delete mode 100644 arch/riscv/include/asm/dma-mapping.h
 delete mode 100644 arch/s390/include/asm/dma-mapping.h
 create mode 100644 include/asm-generic/dma-mapping.h
MAINTAINERS +1 -0
index 7521b063b499..a8b35d9f41b2 100644
@@ -4340,6 +4340,7 @@ F:	lib/dma-noop.c
 F:	lib/dma-virt.c
 F:	drivers/base/dma-mapping.c
 F:	drivers/base/dma-coherent.c
+F:	include/asm-generic/dma-mapping.h
 F:	include/linux/dma-direct.h
 F:	include/linux/dma-mapping.h
 
arch/m32r/include/asm/Kbuild +1 -0
index 7e11b125c35e..ca83fda8177b 100644
@@ -1,5 +1,6 @@
 generic-y += clkdev.h
 generic-y += current.h
+generic-y += dma-mapping.h
 generic-y += exec.h
 generic-y += extable.h
 generic-y += irq_work.h
arch/m32r/include/asm/dma-mapping.h deleted +0 -17
deleted file mode 100644
index 8967fb659691..000000000000
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_M32R_DMA_MAPPING_H
-#define _ASM_M32R_DMA_MAPPING_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-#include <linux/io.h>
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &dma_noop_ops;
-}
-
-#endif /* _ASM_M32R_DMA_MAPPING_H */
arch/riscv/include/asm/Kbuild +1 -0
index 970460a0b492..197460ccbf21 100644
@@ -7,6 +7,7 @@ generic-y += device.h
 generic-y += div64.h
 generic-y += dma.h
 generic-y += dma-contiguous.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += errno.h
 generic-y += exec.h
arch/riscv/include/asm/dma-mapping.h deleted +0 -30
deleted file mode 100644
index 73849e2cc761..000000000000
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Hewlett-Packard Co
- *	David Mosberger-Tang <[email protected]>
- * Copyright (C) 2012 ARM Ltd.
- * Copyright (C) 2016 SiFive, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __ASM_RISCV_DMA_MAPPING_H
-#define __ASM_RISCV_DMA_MAPPING_H
-
-/* Use ops->dma_mapping_error (if it exists) or assume success */
-// #undef DMA_ERROR_CODE
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &dma_noop_ops;
-}
-
-#endif	/* __ASM_RISCV_DMA_MAPPING_H */
arch/s390/include/asm/Kbuild +1 -0
index 048450869328..dade72be127b 100644
@@ -4,6 +4,7 @@ generic-y += cacheflush.h
 generic-y += clkdev.h
 generic-y += device.h
 generic-y += dma-contiguous.h
+generic-y += dma-mapping.h
 generic-y += div64.h
 generic-y += emergency-restart.h
 generic-y += export.h
arch/s390/include/asm/dma-mapping.h deleted +0 -17
deleted file mode 100644
index bdc2455483f6..000000000000
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_S390_DMA_MAPPING_H
-#define _ASM_S390_DMA_MAPPING_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-#include <linux/io.h>
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &dma_noop_ops;
-}
-
-#endif /* _ASM_S390_DMA_MAPPING_H */
include/asm-generic/dma-mapping.h new file +10 -0
new file mode 100644
index 000000000000..164031531d85
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_DMA_MAPPING_H
+#define _ASM_GENERIC_DMA_MAPPING_H
+
+static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
+{
+	return &dma_noop_ops;
+}
+
+#endif /* _ASM_GENERIC_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#74 lore raw

PATCH 24/67 dma-mapping: provide a generic asm/dma-mapping.h

In reply to Christoph Hellwig

For architectures that just use the generic dma_noop_ops we can provide a generic version of dma-mapping.h.

---
 MAINTAINERS                          |  1 +
 arch/m32r/include/asm/Kbuild         |  1 +
 arch/m32r/include/asm/dma-mapping.h  | 17 -----------------
 arch/riscv/include/asm/Kbuild        |  1 +
 arch/riscv/include/asm/dma-mapping.h | 30 ------------------------------
 arch/s390/include/asm/Kbuild         |  1 +
 arch/s390/include/asm/dma-mapping.h  | 17 -----------------
 include/asm-generic/dma-mapping.h    | 10 ++++++++++
 8 files changed, 14 insertions(+), 64 deletions(-)
 delete mode 100644 arch/m32r/include/asm/dma-mapping.h
 delete mode 100644 arch/riscv/include/asm/dma-mapping.h
 delete mode 100644 arch/s390/include/asm/dma-mapping.h
 create mode 100644 include/asm-generic/dma-mapping.h
MAINTAINERS +1 -0
index 7521b063b499..a8b35d9f41b2 100644
@@ -4340,6 +4340,7 @@ F:	lib/dma-noop.c
 F:	lib/dma-virt.c
 F:	drivers/base/dma-mapping.c
 F:	drivers/base/dma-coherent.c
+F:	include/asm-generic/dma-mapping.h
 F:	include/linux/dma-direct.h
 F:	include/linux/dma-mapping.h
 
arch/m32r/include/asm/Kbuild +1 -0
index 7e11b125c35e..ca83fda8177b 100644
@@ -1,5 +1,6 @@
 generic-y += clkdev.h
 generic-y += current.h
+generic-y += dma-mapping.h
 generic-y += exec.h
 generic-y += extable.h
 generic-y += irq_work.h
arch/m32r/include/asm/dma-mapping.h deleted +0 -17
deleted file mode 100644
index 8967fb659691..000000000000
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_M32R_DMA_MAPPING_H
-#define _ASM_M32R_DMA_MAPPING_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-#include <linux/io.h>
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &dma_noop_ops;
-}
-
-#endif /* _ASM_M32R_DMA_MAPPING_H */
arch/riscv/include/asm/Kbuild +1 -0
index 970460a0b492..197460ccbf21 100644
@@ -7,6 +7,7 @@ generic-y += device.h
 generic-y += div64.h
 generic-y += dma.h
 generic-y += dma-contiguous.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += errno.h
 generic-y += exec.h
arch/riscv/include/asm/dma-mapping.h deleted +0 -30
deleted file mode 100644
index 73849e2cc761..000000000000
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Hewlett-Packard Co
- *	David Mosberger-Tang <[email protected]>
- * Copyright (C) 2012 ARM Ltd.
- * Copyright (C) 2016 SiFive, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __ASM_RISCV_DMA_MAPPING_H
-#define __ASM_RISCV_DMA_MAPPING_H
-
-/* Use ops->dma_mapping_error (if it exists) or assume success */
-// #undef DMA_ERROR_CODE
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &dma_noop_ops;
-}
-
-#endif	/* __ASM_RISCV_DMA_MAPPING_H */
arch/s390/include/asm/Kbuild +1 -0
index 048450869328..dade72be127b 100644
@@ -4,6 +4,7 @@ generic-y += cacheflush.h
 generic-y += clkdev.h
 generic-y += device.h
 generic-y += dma-contiguous.h
+generic-y += dma-mapping.h
 generic-y += div64.h
 generic-y += emergency-restart.h
 generic-y += export.h
arch/s390/include/asm/dma-mapping.h deleted +0 -17
deleted file mode 100644
index bdc2455483f6..000000000000
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_S390_DMA_MAPPING_H
-#define _ASM_S390_DMA_MAPPING_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-#include <linux/io.h>
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &dma_noop_ops;
-}
-
-#endif /* _ASM_S390_DMA_MAPPING_H */
include/asm-generic/dma-mapping.h new file +10 -0
new file mode 100644
index 000000000000..164031531d85
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_DMA_MAPPING_H
+#define _ASM_GENERIC_DMA_MAPPING_H
+
+static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
+{
+	return &dma_noop_ops;
+}
+
+#endif /* _ASM_GENERIC_DMA_MAPPING_H */
Signature · 1 line
2.14.2
#75 lore raw

PATCH 25/67 dma-direct: rename dma_noop to dma_direct

In reply to Christoph Hellwig

The trivial direct mapping implementation already does a virtual to physical translation which isn't strictly a noop, and will soon learn to do non-direct but linear physical to dma translations through the device offset and a few small tricks. Rename it to a better fitting name.

---
 MAINTAINERS                        |  2 +-
 arch/arm/Kconfig                   |  2 +-
 arch/arm/include/asm/dma-mapping.h |  2 +-
 arch/arm/mm/dma-mapping-nommu.c    |  8 ++++----
 arch/m32r/Kconfig                  |  2 +-
 arch/riscv/Kconfig                 |  2 +-
 arch/s390/Kconfig                  |  2 +-
 include/asm-generic/dma-mapping.h  |  2 +-
 include/linux/dma-mapping.h        |  2 +-
 lib/Kconfig                        |  2 +-
 lib/Makefile                       |  2 +-
 lib/{dma-noop.c => dma-direct.c}   | 35 +++++++++++++++--------------------
 12 files changed, 29 insertions(+), 34 deletions(-)
 rename lib/{dma-noop.c => dma-direct.c} (53%)
MAINTAINERS +1 -1
index a8b35d9f41b2..b4005fe06e4c 100644
@@ -4336,7 +4336,7 @@ T:	git git://git.infradead.org/users/hch/dma-mapping.git
 W:	http://git.infradead.org/users/hch/dma-mapping.git
 S:	Supported
 F:	lib/dma-debug.c
-F:	lib/dma-noop.c
+F:	lib/dma-direct.c
 F:	lib/dma-virt.c
 F:	drivers/base/dma-mapping.c
 F:	drivers/base/dma-coherent.c
arch/arm/Kconfig +1 -1
index 00d889a37965..430a0aa710d6 100644
@@ -25,7 +25,7 @@ config ARM
 	select CLONE_BACKWARDS
 	select CPU_PM if (SUSPEND || CPU_IDLE)
 	select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
-	select DMA_NOOP_OPS if !MMU
+	select DMA_DIRECT_OPS if !MMU
 	select EDAC_SUPPORT
 	select EDAC_ATOMIC_SCRUB
 	select GENERIC_ALLOCATOR
arch/arm/include/asm/dma-mapping.h +1 -1
index e5d9020c9ee1..8436f6ade57d 100644
@@ -18,7 +18,7 @@ extern const struct dma_map_ops arm_coherent_dma_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-	return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_noop_ops;
+	return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_direct_ops;
 }
 
 #ifdef __arch_page_to_dma
arch/arm/mm/dma-mapping-nommu.c +4 -4
index 1cced700e45a..49e9831dc0f1 100644
@@ -22,7 +22,7 @@
 #include "dma.h"
 
 /*
- *  dma_noop_ops is used if
+ *  dma_direct_ops is used if
  *   - MMU/MPU is off
  *   - cpu is v7m w/o cache support
  *   - device is coherent
@@ -39,7 +39,7 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 				 unsigned long attrs)
 
 {
-	const struct dma_map_ops *ops = &dma_noop_ops;
+	const struct dma_map_ops *ops = &dma_direct_ops;
 	void *ret;
 
 	/*
@@ -70,7 +70,7 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr,
 			       unsigned long attrs)
 {
-	const struct dma_map_ops *ops = &dma_noop_ops;
+	const struct dma_map_ops *ops = &dma_direct_ops;
 
 	if (attrs & DMA_ATTR_NON_CONSISTENT) {
 		ops->free(dev, size, cpu_addr, dma_addr, attrs);
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(arm_nommu_dma_ops);
 
 static const struct dma_map_ops *arm_nommu_get_dma_map_ops(bool coherent)
 {
-	return coherent ? &dma_noop_ops : &arm_nommu_dma_ops;
+	return coherent ? &dma_direct_ops : &arm_nommu_dma_ops;
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
arch/m32r/Kconfig +1 -1
index 498398d915c1..dd84ee194579 100644
@@ -19,7 +19,7 @@ config M32R
 	select MODULES_USE_ELF_RELA
 	select HAVE_DEBUG_STACKOVERFLOW
 	select CPU_NO_EFFICIENT_FFS
-	select DMA_NOOP_OPS
+	select DMA_DIRECT_OPS
 	select ARCH_NO_COHERENT_DMA_MMAP if !MMU
 
 config SBUS
arch/riscv/Kconfig +1 -1
index 2c6adf12713a..865e14f50c14 100644
@@ -83,7 +83,7 @@ config PGTABLE_LEVELS
 config HAVE_KPROBES
 	def_bool n
 
-config DMA_NOOP_OPS
+config DMA_DIRECT_OPS
 	def_bool y
 
 menu "Platform type"
arch/s390/Kconfig +1 -1
index 829c67986db7..9376637229c9 100644
@@ -140,7 +140,7 @@ config S390
 	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_DMA_API_DEBUG
 	select HAVE_DMA_CONTIGUOUS
-	select DMA_NOOP_OPS
+	select DMA_DIRECT_OPS
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS
include/asm-generic/dma-mapping.h +1 -1
index 164031531d85..880a292d792f 100644
@@ -4,7 +4,7 @@
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-	return &dma_noop_ops;
+	return &dma_direct_ops;
 }
 
 #endif /* _ASM_GENERIC_DMA_MAPPING_H */
include/linux/dma-mapping.h +1 -1
index 72568bf4fc12..ff3528de5322 100644
@@ -143,7 +143,7 @@ struct dma_map_ops {
 	bool is_phys;
 };
 
-extern const struct dma_map_ops dma_noop_ops;
+extern const struct dma_map_ops dma_direct_ops;
 extern const struct dma_map_ops dma_virt_ops;
 
 #define DMA_BIT_MASK(n)	(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
lib/Kconfig +1 -1
index c5e84fbcb30b..9d3d649c9dc9 100644
@@ -409,7 +409,7 @@ config HAS_DMA
 	depends on !NO_DMA
 	default y
 
-config DMA_NOOP_OPS
+config DMA_DIRECT_OPS
 	bool
 	depends on HAS_DMA && (!64BIT || ARCH_DMA_ADDR_T_64BIT)
 	default n
lib/Makefile +1 -1
index d11c48ec8ffd..749851abe85a 100644
@@ -28,7 +28,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
-lib-$(CONFIG_DMA_NOOP_OPS) += dma-noop.o
+lib-$(CONFIG_DMA_DIRECT_OPS) += dma-direct.o
 lib-$(CONFIG_DMA_VIRT_OPS) += dma-virt.o
 
 lib-y	+= kobject.o klist.o
lib/dma-direct.c renamed from lib/dma-noop.c +15 -20
similarity index 53%
rename from lib/dma-noop.c
rename to lib/dma-direct.c
index c3728a0551f5..439db40854b7 100644
@@ -10,9 +10,8 @@
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
-static void *dma_noop_alloc(struct device *dev, size_t size,
-			    dma_addr_t *dma_handle, gfp_t gfp,
-			    unsigned long attrs)
+static void *dma_direct_alloc(struct device *dev, size_t size,
+		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
 	void *ret;
 
@@ -23,24 +22,21 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
 	return ret;
 }
 
-static void dma_noop_free(struct device *dev, size_t size,
-			  void *cpu_addr, dma_addr_t dma_addr,
-			  unsigned long attrs)
+static void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+		dma_addr_t dma_addr, unsigned long attrs)
 {
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
 
-static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir,
-				      unsigned long attrs)
+static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
+		unsigned long offset, size_t size, enum dma_data_direction dir,
+		unsigned long attrs)
 {
 	return page_to_phys(page) + offset - PFN_PHYS(dev->dma_pfn_offset);
 }
 
-static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir,
-			     unsigned long attrs)
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	int i;
 	struct scatterlist *sg;
@@ -58,12 +54,11 @@ static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nent
 	return nents;
 }
 
-const struct dma_map_ops dma_noop_ops = {
-	.alloc			= dma_noop_alloc,
-	.free			= dma_noop_free,
-	.map_page		= dma_noop_map_page,
-	.map_sg			= dma_noop_map_sg,
+const struct dma_map_ops dma_direct_ops = {
+	.alloc			= dma_direct_alloc,
+	.free			= dma_direct_free,
+	.map_page		= dma_direct_map_page,
+	.map_sg			= dma_direct_map_sg,
 	.is_phys		= true,
 };
-
-EXPORT_SYMBOL(dma_noop_ops);
+EXPORT_SYMBOL(dma_direct_ops);
Signature · 1 line
2.14.2
Reviewed-by on v1 25/67
#76 lore raw

Re: [PATCH 25/67] dma-direct: rename dma_noop to dma_direct

Quoted 254 lines · Christoph Hellwig

The trivial direct mapping implementation already does a virtual to physical translation which isn't strictly a noop, and will soon learn to do non-direct but linear physical to dma translations through the device offset and a few small tricks. Rename it to a better fitting name.

---
 MAINTAINERS                        |  2 +-
 arch/arm/Kconfig                   |  2 +-
 arch/arm/include/asm/dma-mapping.h |  2 +-
 arch/arm/mm/dma-mapping-nommu.c    |  8 ++++----
 arch/m32r/Kconfig                  |  2 +-
 arch/riscv/Kconfig                 |  2 +-
 arch/s390/Kconfig                  |  2 +-
 include/asm-generic/dma-mapping.h  |  2 +-
 include/linux/dma-mapping.h        |  2 +-
 lib/Kconfig                        |  2 +-
 lib/Makefile                       |  2 +-
 lib/{dma-noop.c => dma-direct.c}   | 35 +++++++++++++++--------------------
 12 files changed, 29 insertions(+), 34 deletions(-)
 rename lib/{dma-noop.c => dma-direct.c} (53%)
MAINTAINERS +1 -1
index a8b35d9f41b2..b4005fe06e4c 100644
@@ -4336,7 +4336,7 @@ T:	git git://git.infradead.org/users/hch/dma-mapping.git
 W:	http://git.infradead.org/users/hch/dma-mapping.git
 S:	Supported
 F:	lib/dma-debug.c
-F:	lib/dma-noop.c
+F:	lib/dma-direct.c
 F:	lib/dma-virt.c
 F:	drivers/base/dma-mapping.c
 F:	drivers/base/dma-coherent.c
arch/arm/Kconfig +1 -1
index 00d889a37965..430a0aa710d6 100644
@@ -25,7 +25,7 @@ config ARM
 	select CLONE_BACKWARDS
 	select CPU_PM if (SUSPEND || CPU_IDLE)
 	select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
-	select DMA_NOOP_OPS if !MMU
+	select DMA_DIRECT_OPS if !MMU
 	select EDAC_SUPPORT
 	select EDAC_ATOMIC_SCRUB
 	select GENERIC_ALLOCATOR
arch/arm/include/asm/dma-mapping.h +1 -1
index e5d9020c9ee1..8436f6ade57d 100644
@@ -18,7 +18,7 @@ extern const struct dma_map_ops arm_coherent_dma_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-	return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_noop_ops;
+	return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_direct_ops;
 }
 
 #ifdef __arch_page_to_dma
arch/arm/mm/dma-mapping-nommu.c +4 -4
index 1cced700e45a..49e9831dc0f1 100644
@@ -22,7 +22,7 @@
 #include "dma.h"
 
 /*
- *  dma_noop_ops is used if
+ *  dma_direct_ops is used if
  *   - MMU/MPU is off
  *   - cpu is v7m w/o cache support
  *   - device is coherent
@@ -39,7 +39,7 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 				 unsigned long attrs)
 
 {
-	const struct dma_map_ops *ops = &dma_noop_ops;
+	const struct dma_map_ops *ops = &dma_direct_ops;
 	void *ret;
 
 	/*
@@ -70,7 +70,7 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr,
 			       unsigned long attrs)
 {
-	const struct dma_map_ops *ops = &dma_noop_ops;
+	const struct dma_map_ops *ops = &dma_direct_ops;
 
 	if (attrs & DMA_ATTR_NON_CONSISTENT) {
 		ops->free(dev, size, cpu_addr, dma_addr, attrs);
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(arm_nommu_dma_ops);
 
 static const struct dma_map_ops *arm_nommu_get_dma_map_ops(bool coherent)
 {
-	return coherent ? &dma_noop_ops : &arm_nommu_dma_ops;
+	return coherent ? &dma_direct_ops : &arm_nommu_dma_ops;
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
arch/m32r/Kconfig +1 -1
index 498398d915c1..dd84ee194579 100644
@@ -19,7 +19,7 @@ config M32R
 	select MODULES_USE_ELF_RELA
 	select HAVE_DEBUG_STACKOVERFLOW
 	select CPU_NO_EFFICIENT_FFS
-	select DMA_NOOP_OPS
+	select DMA_DIRECT_OPS
 	select ARCH_NO_COHERENT_DMA_MMAP if !MMU
 
 config SBUS
arch/riscv/Kconfig +1 -1
index 2c6adf12713a..865e14f50c14 100644
@@ -83,7 +83,7 @@ config PGTABLE_LEVELS
 config HAVE_KPROBES
 	def_bool n
 
-config DMA_NOOP_OPS
+config DMA_DIRECT_OPS
 	def_bool y
 
 menu "Platform type"
arch/s390/Kconfig +1 -1
index 829c67986db7..9376637229c9 100644
@@ -140,7 +140,7 @@ config S390
 	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_DMA_API_DEBUG
 	select HAVE_DMA_CONTIGUOUS
-	select DMA_NOOP_OPS
+	select DMA_DIRECT_OPS
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS
include/asm-generic/dma-mapping.h +1 -1
index 164031531d85..880a292d792f 100644
@@ -4,7 +4,7 @@
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-	return &dma_noop_ops;
+	return &dma_direct_ops;
 }
 
 #endif /* _ASM_GENERIC_DMA_MAPPING_H */
include/linux/dma-mapping.h +1 -1
index 72568bf4fc12..ff3528de5322 100644
@@ -143,7 +143,7 @@ struct dma_map_ops {
 	bool is_phys;
 };
 
-extern const struct dma_map_ops dma_noop_ops;
+extern const struct dma_map_ops dma_direct_ops;
 extern const struct dma_map_ops dma_virt_ops;
 
 #define DMA_BIT_MASK(n)	(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
lib/Kconfig +1 -1
index c5e84fbcb30b..9d3d649c9dc9 100644
@@ -409,7 +409,7 @@ config HAS_DMA
 	depends on !NO_DMA
 	default y
 
-config DMA_NOOP_OPS
+config DMA_DIRECT_OPS
 	bool
 	depends on HAS_DMA && (!64BIT || ARCH_DMA_ADDR_T_64BIT)
 	default n
lib/Makefile +1 -1
index d11c48ec8ffd..749851abe85a 100644
@@ -28,7 +28,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
-lib-$(CONFIG_DMA_NOOP_OPS) += dma-noop.o
+lib-$(CONFIG_DMA_DIRECT_OPS) += dma-direct.o
 lib-$(CONFIG_DMA_VIRT_OPS) += dma-virt.o
 
 lib-y	+= kobject.o klist.o
lib/dma-direct.c renamed from lib/dma-noop.c +9 -18
similarity index 53%
rename from lib/dma-noop.c
rename to lib/dma-direct.c
index c3728a0551f5..439db40854b7 100644
@@ -10,9 +10,8 @@
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
-static void *dma_noop_alloc(struct device *dev, size_t size,
-			    dma_addr_t *dma_handle, gfp_t gfp,
-			    unsigned long attrs)
+static void *dma_direct_alloc(struct device *dev, size_t size,
+		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
 	void *ret;
 
@@ -23,24 +22,21 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
 	return ret;
 }
 
-static void dma_noop_free(struct device *dev, size_t size,
-			  void *cpu_addr, dma_addr_t dma_addr,
-			  unsigned long attrs)
+static void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+		dma_addr_t dma_addr, unsigned long attrs)
 {
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
 
-static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir,
-				      unsigned long attrs)
+static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
+		unsigned long offset, size_t size, enum dma_data_direction dir,
+		unsigned long attrs)
 {
 	return page_to_phys(page) + offset - PFN_PHYS(dev->dma_pfn_offset);
 }
 
-static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir,
-			     unsigned long attrs)
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	int i;
 	struct scatterlist *sg;
@@ -58,12 +54,11 @@ static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nent
 	return nents;
 }
 
-const struct dma_map_ops dma_noop_ops = {
-	.alloc			= dma_noop_alloc,
-	.free			= dma_noop_free,
-	.map_page		= dma_noop_map_page,
-	.map_sg			= dma_noop_map_sg,

lib/dma-direct.c static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nent · line 64

Quoted 10 lines
lib/dma-direct.c renamed from lib/dma-noop.c +6 -2
+const struct dma_map_ops dma_direct_ops = {
+	.alloc			= dma_direct_alloc,
+	.free			= dma_direct_free,
+	.map_page		= dma_direct_map_page,
+	.map_sg			= dma_direct_map_sg,
 	.is_phys		= true,
 };
-
-EXPORT_SYMBOL(dma_noop_ops);
+EXPORT_SYMBOL(dma_direct_ops);

From ARM NOMMU perspective

Thanks
Vladimir

Reviewed-by on v1 25/67
#77 lore raw

Re: [PATCH 25/67] dma-direct: rename dma_noop to dma_direct

In reply to Christoph Hellwig
Quoted 265 lines · Christoph Hellwig

The trivial direct mapping implementation already does a virtual to physical translation which isn't strictly a noop, and will soon learn to do non-direct but linear physical to dma translations through the device offset and a few small tricks. Rename it to a better fitting name.

---
 MAINTAINERS                        |  2 +-
 arch/arm/Kconfig                   |  2 +-
 arch/arm/include/asm/dma-mapping.h |  2 +-
 arch/arm/mm/dma-mapping-nommu.c    |  8 ++++----
 arch/m32r/Kconfig                  |  2 +-
 arch/riscv/Kconfig                 |  2 +-
 arch/s390/Kconfig                  |  2 +-
 include/asm-generic/dma-mapping.h  |  2 +-
 include/linux/dma-mapping.h        |  2 +-
 lib/Kconfig                        |  2 +-
 lib/Makefile                       |  2 +-
 lib/{dma-noop.c => dma-direct.c}   | 35 +++++++++++++++--------------------
 12 files changed, 29 insertions(+), 34 deletions(-)
 rename lib/{dma-noop.c => dma-direct.c} (53%)
MAINTAINERS +1 -1
index a8b35d9f41b2..b4005fe06e4c 100644
@@ -4336,7 +4336,7 @@ T:	git git://git.infradead.org/users/hch/dma-mapping.git
 W:	http://git.infradead.org/users/hch/dma-mapping.git
 S:	Supported
 F:	lib/dma-debug.c
-F:	lib/dma-noop.c
+F:	lib/dma-direct.c
 F:	lib/dma-virt.c
 F:	drivers/base/dma-mapping.c
 F:	drivers/base/dma-coherent.c
arch/arm/Kconfig +1 -1
index 00d889a37965..430a0aa710d6 100644
@@ -25,7 +25,7 @@ config ARM
 	select CLONE_BACKWARDS
 	select CPU_PM if (SUSPEND || CPU_IDLE)
 	select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
-	select DMA_NOOP_OPS if !MMU
+	select DMA_DIRECT_OPS if !MMU
 	select EDAC_SUPPORT
 	select EDAC_ATOMIC_SCRUB
 	select GENERIC_ALLOCATOR
arch/arm/include/asm/dma-mapping.h +1 -1
index e5d9020c9ee1..8436f6ade57d 100644
@@ -18,7 +18,7 @@ extern const struct dma_map_ops arm_coherent_dma_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-	return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_noop_ops;
+	return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_direct_ops;
 }
 
 #ifdef __arch_page_to_dma
arch/arm/mm/dma-mapping-nommu.c +4 -4
index 1cced700e45a..49e9831dc0f1 100644
@@ -22,7 +22,7 @@
 #include "dma.h"
 
 /*
- *  dma_noop_ops is used if
+ *  dma_direct_ops is used if
  *   - MMU/MPU is off
  *   - cpu is v7m w/o cache support
  *   - device is coherent
@@ -39,7 +39,7 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 				 unsigned long attrs)
 
 {
-	const struct dma_map_ops *ops = &dma_noop_ops;
+	const struct dma_map_ops *ops = &dma_direct_ops;
 	void *ret;
 
 	/*
@@ -70,7 +70,7 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr,
 			       unsigned long attrs)
 {
-	const struct dma_map_ops *ops = &dma_noop_ops;
+	const struct dma_map_ops *ops = &dma_direct_ops;
 
 	if (attrs & DMA_ATTR_NON_CONSISTENT) {
 		ops->free(dev, size, cpu_addr, dma_addr, attrs);
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(arm_nommu_dma_ops);
 
 static const struct dma_map_ops *arm_nommu_get_dma_map_ops(bool coherent)
 {
-	return coherent ? &dma_noop_ops : &arm_nommu_dma_ops;
+	return coherent ? &dma_direct_ops : &arm_nommu_dma_ops;
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
arch/m32r/Kconfig +1 -1
index 498398d915c1..dd84ee194579 100644
@@ -19,7 +19,7 @@ config M32R
 	select MODULES_USE_ELF_RELA
 	select HAVE_DEBUG_STACKOVERFLOW
 	select CPU_NO_EFFICIENT_FFS
-	select DMA_NOOP_OPS
+	select DMA_DIRECT_OPS
 	select ARCH_NO_COHERENT_DMA_MMAP if !MMU
 
 config SBUS
arch/riscv/Kconfig +1 -1
index 2c6adf12713a..865e14f50c14 100644
@@ -83,7 +83,7 @@ config PGTABLE_LEVELS
 config HAVE_KPROBES
 	def_bool n
 
-config DMA_NOOP_OPS
+config DMA_DIRECT_OPS
 	def_bool y
 
 menu "Platform type"
arch/s390/Kconfig +1 -1
index 829c67986db7..9376637229c9 100644
@@ -140,7 +140,7 @@ config S390
 	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_DMA_API_DEBUG
 	select HAVE_DMA_CONTIGUOUS
-	select DMA_NOOP_OPS
+	select DMA_DIRECT_OPS
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS
include/asm-generic/dma-mapping.h +1 -1
index 164031531d85..880a292d792f 100644
@@ -4,7 +4,7 @@
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-	return &dma_noop_ops;
+	return &dma_direct_ops;
 }
 
 #endif /* _ASM_GENERIC_DMA_MAPPING_H */
include/linux/dma-mapping.h +1 -1
index 72568bf4fc12..ff3528de5322 100644
@@ -143,7 +143,7 @@ struct dma_map_ops {
 	bool is_phys;
 };
 
-extern const struct dma_map_ops dma_noop_ops;
+extern const struct dma_map_ops dma_direct_ops;
 extern const struct dma_map_ops dma_virt_ops;
 
 #define DMA_BIT_MASK(n)	(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
lib/Kconfig +1 -1
index c5e84fbcb30b..9d3d649c9dc9 100644
@@ -409,7 +409,7 @@ config HAS_DMA
 	depends on !NO_DMA
 	default y
 
-config DMA_NOOP_OPS
+config DMA_DIRECT_OPS
 	bool
 	depends on HAS_DMA && (!64BIT || ARCH_DMA_ADDR_T_64BIT)
 	default n
lib/Makefile +1 -1
index d11c48ec8ffd..749851abe85a 100644
@@ -28,7 +28,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
-lib-$(CONFIG_DMA_NOOP_OPS) += dma-noop.o
+lib-$(CONFIG_DMA_DIRECT_OPS) += dma-direct.o
 lib-$(CONFIG_DMA_VIRT_OPS) += dma-virt.o
 
 lib-y	+= kobject.o klist.o
lib/dma-direct.c renamed from lib/dma-noop.c +15 -20
similarity index 53%
rename from lib/dma-noop.c
rename to lib/dma-direct.c
index c3728a0551f5..439db40854b7 100644
@@ -10,9 +10,8 @@
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
-static void *dma_noop_alloc(struct device *dev, size_t size,
-			    dma_addr_t *dma_handle, gfp_t gfp,
-			    unsigned long attrs)
+static void *dma_direct_alloc(struct device *dev, size_t size,
+		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
 	void *ret;
 
@@ -23,24 +22,21 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
 	return ret;
 }
 
-static void dma_noop_free(struct device *dev, size_t size,
-			  void *cpu_addr, dma_addr_t dma_addr,
-			  unsigned long attrs)
+static void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+		dma_addr_t dma_addr, unsigned long attrs)
 {
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
 
-static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir,
-				      unsigned long attrs)
+static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
+		unsigned long offset, size_t size, enum dma_data_direction dir,
+		unsigned long attrs)
 {
 	return page_to_phys(page) + offset - PFN_PHYS(dev->dma_pfn_offset);
 }
 
-static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir,
-			     unsigned long attrs)
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	int i;
 	struct scatterlist *sg;
@@ -58,12 +54,11 @@ static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nent
 	return nents;
 }
 
-const struct dma_map_ops dma_noop_ops = {
-	.alloc			= dma_noop_alloc,
-	.free			= dma_noop_free,
-	.map_page		= dma_noop_map_page,
-	.map_sg			= dma_noop_map_sg,
+const struct dma_map_ops dma_direct_ops = {
+	.alloc			= dma_direct_alloc,
+	.free			= dma_direct_free,
+	.map_page		= dma_direct_map_page,
+	.map_sg			= dma_direct_map_sg,
 	.is_phys		= true,
 };
-
-EXPORT_SYMBOL(dma_noop_ops);
+EXPORT_SYMBOL(dma_direct_ops);
Quoted 1 line

From ARM NOMMU perspective

Thanks
Vladimir

#78 lore raw

PATCH 25/67 dma-direct: rename dma_noop to dma_direct

In reply to Christoph Hellwig

The trivial direct mapping implementation already does a virtual to physical translation which isn't strictly a noop, and will soon learn to do non-direct but linear physical to dma translations through the device offset and a few small tricks. Rename it to a better fitting name.

---
 MAINTAINERS                        |  2 +-
 arch/arm/Kconfig                   |  2 +-
 arch/arm/include/asm/dma-mapping.h |  2 +-
 arch/arm/mm/dma-mapping-nommu.c    |  8 ++++----
 arch/m32r/Kconfig                  |  2 +-
 arch/riscv/Kconfig                 |  2 +-
 arch/s390/Kconfig                  |  2 +-
 include/asm-generic/dma-mapping.h  |  2 +-
 include/linux/dma-mapping.h        |  2 +-
 lib/Kconfig                        |  2 +-
 lib/Makefile                       |  2 +-
 lib/{dma-noop.c => dma-direct.c}   | 35 +++++++++++++++--------------------
 12 files changed, 29 insertions(+), 34 deletions(-)
 rename lib/{dma-noop.c => dma-direct.c} (53%)
MAINTAINERS +1 -1
index a8b35d9f41b2..b4005fe06e4c 100644
@@ -4336,7 +4336,7 @@ T:	git git://git.infradead.org/users/hch/dma-mapping.git
 W:	http://git.infradead.org/users/hch/dma-mapping.git
 S:	Supported
 F:	lib/dma-debug.c
-F:	lib/dma-noop.c
+F:	lib/dma-direct.c
 F:	lib/dma-virt.c
 F:	drivers/base/dma-mapping.c
 F:	drivers/base/dma-coherent.c
arch/arm/Kconfig +1 -1
index 00d889a37965..430a0aa710d6 100644
@@ -25,7 +25,7 @@ config ARM
 	select CLONE_BACKWARDS
 	select CPU_PM if (SUSPEND || CPU_IDLE)
 	select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
-	select DMA_NOOP_OPS if !MMU
+	select DMA_DIRECT_OPS if !MMU
 	select EDAC_SUPPORT
 	select EDAC_ATOMIC_SCRUB
 	select GENERIC_ALLOCATOR
arch/arm/include/asm/dma-mapping.h +1 -1
index e5d9020c9ee1..8436f6ade57d 100644
@@ -18,7 +18,7 @@ extern const struct dma_map_ops arm_coherent_dma_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-	return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_noop_ops;
+	return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_direct_ops;
 }
 
 #ifdef __arch_page_to_dma
arch/arm/mm/dma-mapping-nommu.c +4 -4
index 1cced700e45a..49e9831dc0f1 100644
@@ -22,7 +22,7 @@
 #include "dma.h"
 
 /*
- *  dma_noop_ops is used if
+ *  dma_direct_ops is used if
  *   - MMU/MPU is off
  *   - cpu is v7m w/o cache support
  *   - device is coherent
@@ -39,7 +39,7 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 				 unsigned long attrs)
 
 {
-	const struct dma_map_ops *ops = &dma_noop_ops;
+	const struct dma_map_ops *ops = &dma_direct_ops;
 	void *ret;
 
 	/*
@@ -70,7 +70,7 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr,
 			       unsigned long attrs)
 {
-	const struct dma_map_ops *ops = &dma_noop_ops;
+	const struct dma_map_ops *ops = &dma_direct_ops;
 
 	if (attrs & DMA_ATTR_NON_CONSISTENT) {
 		ops->free(dev, size, cpu_addr, dma_addr, attrs);
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(arm_nommu_dma_ops);
 
 static const struct dma_map_ops *arm_nommu_get_dma_map_ops(bool coherent)
 {
-	return coherent ? &dma_noop_ops : &arm_nommu_dma_ops;
+	return coherent ? &dma_direct_ops : &arm_nommu_dma_ops;
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
arch/m32r/Kconfig +1 -1
index 498398d915c1..dd84ee194579 100644
@@ -19,7 +19,7 @@ config M32R
 	select MODULES_USE_ELF_RELA
 	select HAVE_DEBUG_STACKOVERFLOW
 	select CPU_NO_EFFICIENT_FFS
-	select DMA_NOOP_OPS
+	select DMA_DIRECT_OPS
 	select ARCH_NO_COHERENT_DMA_MMAP if !MMU
 
 config SBUS
arch/riscv/Kconfig +1 -1
index 2c6adf12713a..865e14f50c14 100644
@@ -83,7 +83,7 @@ config PGTABLE_LEVELS
 config HAVE_KPROBES
 	def_bool n
 
-config DMA_NOOP_OPS
+config DMA_DIRECT_OPS
 	def_bool y
 
 menu "Platform type"
arch/s390/Kconfig +1 -1
index 829c67986db7..9376637229c9 100644
@@ -140,7 +140,7 @@ config S390
 	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_DMA_API_DEBUG
 	select HAVE_DMA_CONTIGUOUS
-	select DMA_NOOP_OPS
+	select DMA_DIRECT_OPS
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS
include/asm-generic/dma-mapping.h +1 -1
index 164031531d85..880a292d792f 100644
@@ -4,7 +4,7 @@
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-	return &dma_noop_ops;
+	return &dma_direct_ops;
 }
 
 #endif /* _ASM_GENERIC_DMA_MAPPING_H */
include/linux/dma-mapping.h +1 -1
index 72568bf4fc12..ff3528de5322 100644
@@ -143,7 +143,7 @@ struct dma_map_ops {
 	bool is_phys;
 };
 
-extern const struct dma_map_ops dma_noop_ops;
+extern const struct dma_map_ops dma_direct_ops;
 extern const struct dma_map_ops dma_virt_ops;
 
 #define DMA_BIT_MASK(n)	(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
lib/Kconfig +1 -1
index c5e84fbcb30b..9d3d649c9dc9 100644
@@ -409,7 +409,7 @@ config HAS_DMA
 	depends on !NO_DMA
 	default y
 
-config DMA_NOOP_OPS
+config DMA_DIRECT_OPS
 	bool
 	depends on HAS_DMA && (!64BIT || ARCH_DMA_ADDR_T_64BIT)
 	default n
lib/Makefile +1 -1
index d11c48ec8ffd..749851abe85a 100644
@@ -28,7 +28,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
-lib-$(CONFIG_DMA_NOOP_OPS) += dma-noop.o
+lib-$(CONFIG_DMA_DIRECT_OPS) += dma-direct.o
 lib-$(CONFIG_DMA_VIRT_OPS) += dma-virt.o
 
 lib-y	+= kobject.o klist.o
lib/dma-direct.c renamed from lib/dma-noop.c +15 -20
similarity index 53%
rename from lib/dma-noop.c
rename to lib/dma-direct.c
index c3728a0551f5..439db40854b7 100644
@@ -10,9 +10,8 @@
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
-static void *dma_noop_alloc(struct device *dev, size_t size,
-			    dma_addr_t *dma_handle, gfp_t gfp,
-			    unsigned long attrs)
+static void *dma_direct_alloc(struct device *dev, size_t size,
+		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
 	void *ret;
 
@@ -23,24 +22,21 @@ static void *dma_noop_alloc(struct device *dev, size_t size,
 	return ret;
 }
 
-static void dma_noop_free(struct device *dev, size_t size,
-			  void *cpu_addr, dma_addr_t dma_addr,
-			  unsigned long attrs)
+static void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+		dma_addr_t dma_addr, unsigned long attrs)
 {
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
 
-static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir,
-				      unsigned long attrs)
+static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
+		unsigned long offset, size_t size, enum dma_data_direction dir,
+		unsigned long attrs)
 {
 	return page_to_phys(page) + offset - PFN_PHYS(dev->dma_pfn_offset);
 }
 
-static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir,
-			     unsigned long attrs)
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	int i;
 	struct scatterlist *sg;
@@ -58,12 +54,11 @@ static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nent
 	return nents;
 }
 
-const struct dma_map_ops dma_noop_ops = {
-	.alloc			= dma_noop_alloc,
-	.free			= dma_noop_free,
-	.map_page		= dma_noop_map_page,
-	.map_sg			= dma_noop_map_sg,
+const struct dma_map_ops dma_direct_ops = {
+	.alloc			= dma_direct_alloc,
+	.free			= dma_direct_free,
+	.map_page		= dma_direct_map_page,
+	.map_sg			= dma_direct_map_sg,
 	.is_phys		= true,
 };
-
-EXPORT_SYMBOL(dma_noop_ops);
+EXPORT_SYMBOL(dma_direct_ops);
Signature · 1 line
2.14.2
#79 lore raw

PATCH 26/67 dma-direct: use phys_to_dma

In reply to Christoph Hellwig

This means it uses whatever linear remapping scheme that the architecture provides is used in the generic dma_direct ops.

---
 lib/dma-direct.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)
lib/dma-direct.c +7 -11
index 439db40854b7..0e087650e86b 100644
@@ -1,12 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- *	lib/dma-noop.c
- *
- * DMA operations that map to physical addresses without flushing memory.
+ * DMA operations that map physical memory directly without using an IOMMU or
+ * flushing caches.
  */
 #include <linux/export.h>
 #include <linux/mm.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
@@ -17,7 +16,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 	if (ret)
-		*dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset);
+		*dma_handle = phys_to_dma(dev, virt_to_phys(ret));
 
 	return ret;
 }
@@ -32,7 +31,7 @@ static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
 		unsigned long offset, size_t size, enum dma_data_direction dir,
 		unsigned long attrs)
 {
-	return page_to_phys(page) + offset - PFN_PHYS(dev->dma_pfn_offset);
+	return phys_to_dma(dev, page_to_phys(page)) + offset;
 }
 
 static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
@@ -42,12 +41,9 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	struct scatterlist *sg;
 
 	for_each_sg(sgl, sg, nents, i) {
-		dma_addr_t offset = PFN_PHYS(dev->dma_pfn_offset);
-		void *va;
-
 		BUG_ON(!sg_page(sg));
-		va = sg_virt(sg);
-		sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va) - offset;
+
+		sg_dma_address(sg) = phys_to_dma(dev, sg_phys(sg));
 		sg_dma_len(sg) = sg->length;
 	}
 
Signature · 1 line
2.14.2
Reviewed-by on v1 26/67
#80 lore raw

Re: [PATCH 26/67] dma-direct: use phys_to_dma

Quoted 52 lines · Christoph Hellwig

This means it uses whatever linear remapping scheme that the architecture provides is used in the generic dma_direct ops.

---
 lib/dma-direct.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)
lib/dma-direct.c +5 -7
index 439db40854b7..0e087650e86b 100644
@@ -1,12 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- *	lib/dma-noop.c
- *
- * DMA operations that map to physical addresses without flushing memory.
+ * DMA operations that map physical memory directly without using an IOMMU or
+ * flushing caches.
  */
 #include <linux/export.h>
 #include <linux/mm.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
@@ -17,7 +16,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 	if (ret)
-		*dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset);
+		*dma_handle = phys_to_dma(dev, virt_to_phys(ret));
 
 	return ret;
 }
@@ -32,7 +31,7 @@ static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
 		unsigned long offset, size_t size, enum dma_data_direction dir,
 		unsigned long attrs)
 {
-	return page_to_phys(page) + offset - PFN_PHYS(dev->dma_pfn_offset);
+	return phys_to_dma(dev, page_to_phys(page)) + offset;
 }
 
 static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
@@ -42,12 +41,9 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	struct scatterlist *sg;
 
 	for_each_sg(sgl, sg, nents, i) {
-		dma_addr_t offset = PFN_PHYS(dev->dma_pfn_offset);

lib/dma-direct.c static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, · line 49

Quoted 10 lines
lib/dma-direct.c +2 -4
-		void *va;
-
 		BUG_ON(!sg_page(sg));
-		va = sg_virt(sg);
-		sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va) - offset;
+
+		sg_dma_address(sg) = phys_to_dma(dev, sg_phys(sg));
 		sg_dma_len(sg) = sg->length;
 	}
 

From ARM NOMMU perspective

Thanks
Vladimir

Reviewed-by on v1 26/67
#81 lore raw

Re: [PATCH 26/67] dma-direct: use phys_to_dma

In reply to Christoph Hellwig
Quoted 63 lines · Christoph Hellwig

This means it uses whatever linear remapping scheme that the architecture provides is used in the generic dma_direct ops.

---
 lib/dma-direct.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)
lib/dma-direct.c +7 -11
index 439db40854b7..0e087650e86b 100644
@@ -1,12 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- *	lib/dma-noop.c
- *
- * DMA operations that map to physical addresses without flushing memory.
+ * DMA operations that map physical memory directly without using an IOMMU or
+ * flushing caches.
  */
 #include <linux/export.h>
 #include <linux/mm.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
@@ -17,7 +16,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 	if (ret)
-		*dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset);
+		*dma_handle = phys_to_dma(dev, virt_to_phys(ret));
 
 	return ret;
 }
@@ -32,7 +31,7 @@ static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
 		unsigned long offset, size_t size, enum dma_data_direction dir,
 		unsigned long attrs)
 {
-	return page_to_phys(page) + offset - PFN_PHYS(dev->dma_pfn_offset);
+	return phys_to_dma(dev, page_to_phys(page)) + offset;
 }
 
 static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
@@ -42,12 +41,9 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	struct scatterlist *sg;
 
 	for_each_sg(sgl, sg, nents, i) {
-		dma_addr_t offset = PFN_PHYS(dev->dma_pfn_offset);
-		void *va;
-
 		BUG_ON(!sg_page(sg));
-		va = sg_virt(sg);
-		sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va) - offset;
+
+		sg_dma_address(sg) = phys_to_dma(dev, sg_phys(sg));
 		sg_dma_len(sg) = sg->length;
 	}
 
Quoted 1 line

From ARM NOMMU perspective

Thanks
Vladimir

#82 lore raw

PATCH 26/67 dma-direct: use phys_to_dma

In reply to Christoph Hellwig

This means it uses whatever linear remapping scheme that the architecture provides is used in the generic dma_direct ops.

---
 lib/dma-direct.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)
lib/dma-direct.c +7 -11
index 439db40854b7..0e087650e86b 100644
@@ -1,12 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- *	lib/dma-noop.c
- *
- * DMA operations that map to physical addresses without flushing memory.
+ * DMA operations that map physical memory directly without using an IOMMU or
+ * flushing caches.
  */
 #include <linux/export.h>
 #include <linux/mm.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
@@ -17,7 +16,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 	if (ret)
-		*dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset);
+		*dma_handle = phys_to_dma(dev, virt_to_phys(ret));
 
 	return ret;
 }
@@ -32,7 +31,7 @@ static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
 		unsigned long offset, size_t size, enum dma_data_direction dir,
 		unsigned long attrs)
 {
-	return page_to_phys(page) + offset - PFN_PHYS(dev->dma_pfn_offset);
+	return phys_to_dma(dev, page_to_phys(page)) + offset;
 }
 
 static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
@@ -42,12 +41,9 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	struct scatterlist *sg;
 
 	for_each_sg(sgl, sg, nents, i) {
-		dma_addr_t offset = PFN_PHYS(dev->dma_pfn_offset);
-		void *va;
-
 		BUG_ON(!sg_page(sg));
-		va = sg_virt(sg);
-		sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va) - offset;
+
+		sg_dma_address(sg) = phys_to_dma(dev, sg_phys(sg));
 		sg_dma_len(sg) = sg->length;
 	}
 
Signature · 1 line
2.14.2
#83 lore raw

PATCH 27/67 dma-direct: add dma address sanity checks

In reply to Christoph Hellwig

Roughly based on the x86 pci-nommu implementation.

---
 lib/dma-direct.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)
lib/dma-direct.c +31 -1
index 0e087650e86b..ddd9dcf4e663 100644
@@ -9,6 +9,24 @@
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
+#define DIRECT_MAPPING_ERROR		0
+
+static bool
+check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
+		const char *caller)
+{
+	if (unlikely(dev && !dma_capable(dev, dma_addr, size))) {
+		if (*dev->dma_mask >= DMA_BIT_MASK(32)) {
+			dev_err(dev,
+				"%s: overflow %llx+%zu of device mask %llx\n",
+				caller, (long long)dma_addr, size,
+				(long long)*dev->dma_mask);
+		}
+		return false;
+	}
+	return true;
+}
+
 static void *dma_direct_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
@@ -31,7 +49,11 @@ static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
 		unsigned long offset, size_t size, enum dma_data_direction dir,
 		unsigned long attrs)
 {
-	return phys_to_dma(dev, page_to_phys(page)) + offset;
+	dma_addr_t dma_addr = phys_to_dma(dev, page_to_phys(page)) + offset;
+
+	if (!check_addr(dev, dma_addr, size, __func__))
+		return DIRECT_MAPPING_ERROR;
+	return dma_addr;
 }
 
 static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
@@ -44,17 +66,25 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 		BUG_ON(!sg_page(sg));
 
 		sg_dma_address(sg) = phys_to_dma(dev, sg_phys(sg));
+		if (!check_addr(dev, sg_dma_address(sg), sg->length, __func__))
+			return 0;
 		sg_dma_len(sg) = sg->length;
 	}
 
 	return nents;
 }
 
+static int dma_direct_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return dma_addr == DIRECT_MAPPING_ERROR;
+}
+
 const struct dma_map_ops dma_direct_ops = {
 	.alloc			= dma_direct_alloc,
 	.free			= dma_direct_free,
 	.map_page		= dma_direct_map_page,
 	.map_sg			= dma_direct_map_sg,
+	.mapping_error		= dma_direct_mapping_error,
 	.is_phys		= true,
 };
 EXPORT_SYMBOL(dma_direct_ops);
Signature · 1 line
2.14.2
#84 lore raw

Re: [PATCH 27/67] dma-direct: add dma address sanity checks

Hi Christoph,

Quoted 3 lines · Christoph Hellwig

Roughly based on the x86 pci-nommu implementation.

Thanks for your patch!

Quoted 6 lines
lib/dma-direct.c +0 -0
@@ -9,6 +9,24 @@
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 

lib/dma-direct.c line 21

Quoted 10 lines
lib/dma-direct.c +10 -0
+#define DIRECT_MAPPING_ERROR           0
+
+static bool
+check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
+               const char *caller)
+{
+       if (unlikely(dev && !dma_capable(dev, dma_addr, size))) {
+               if (*dev->dma_mask >= DMA_BIT_MASK(32)) {
+                       dev_err(dev,
+                               "%s: overflow %llx+%zu of device mask %llx\n",

Please use "%pad" to format dma_addr_t ...

lib/dma-direct.c line 22

Quoted 1 line
lib/dma-direct.c +1 -0
+                               caller, (long long)dma_addr, size,

... and use &dma_addr.

lib/dma-direct.c line 23

Quoted 1 line
lib/dma-direct.c +1 -0
+                               (long long)*dev->dma_mask);

This cast is not needed, as u64 is unsigned long long in kernelspace on all architectures.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#85 lore raw

Re: [PATCH 27/67] dma-direct: add dma address sanity checks

Quoted 10 lines · Geert Uytterhoeven

lib/dma-direct.c line 21

Quoted 7 lines
lib/dma-direct.c +7 -0
+check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
+               const char *caller)
+{
+       if (unlikely(dev && !dma_capable(dev, dma_addr, size))) {
+               if (*dev->dma_mask >= DMA_BIT_MASK(32)) {
+                       dev_err(dev,
+                               "%s: overflow %llx+%zu of device mask %llx\n",

Please use "%pad" to format dma_addr_t ...

Quoted 8 lines
Quoted 1 line

+ caller, (long long)dma_addr, size,

... and use &dma_addr.

Quoted 1 line

+ (long long)*dev->dma_mask);

This cast is not needed, as u64 is unsigned long long in kernelspace on all architectures.

Thanks, fixed.

#86 lore raw

Re: [PATCH 27/67] dma-direct: add dma address sanity checks

In reply to Christoph Hellwig

Hi Christoph,

Quoted 3 lines · Christoph Hellwig

Roughly based on the x86 pci-nommu implementation.

Thanks for your patch!

Quoted 6 lines
lib/dma-direct.c +0 -0
@@ -9,6 +9,24 @@
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 

lib/dma-direct.c line 21

Quoted 10 lines
lib/dma-direct.c +10 -0
+#define DIRECT_MAPPING_ERROR           0
+
+static bool
+check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
+               const char *caller)
+{
+       if (unlikely(dev && !dma_capable(dev, dma_addr, size))) {
+               if (*dev->dma_mask >= DMA_BIT_MASK(32)) {
+                       dev_err(dev,
+                               "%s: overflow %llx+%zu of device mask %llx\n",

Please use "%pad" to format dma_addr_t ...

lib/dma-direct.c line 22

Quoted 1 line
lib/dma-direct.c +1 -0
+                               caller, (long long)dma_addr, size,

... and use &dma_addr.

lib/dma-direct.c line 23

Quoted 1 line
lib/dma-direct.c +1 -0
+                               (long long)*dev->dma_mask);

This cast is not needed, as u64 is unsigned long long in kernelspace on all architectures.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#87 lore raw

PATCH 27/67 dma-direct: add dma address sanity checks

In reply to Christoph Hellwig

Roughly based on the x86 pci-nommu implementation.

---
 lib/dma-direct.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)
lib/dma-direct.c +31 -1
index 0e087650e86b..ddd9dcf4e663 100644
@@ -9,6 +9,24 @@
 #include <linux/scatterlist.h>
 #include <linux/pfn.h>
 
+#define DIRECT_MAPPING_ERROR		0
+
+static bool
+check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
+		const char *caller)
+{
+	if (unlikely(dev && !dma_capable(dev, dma_addr, size))) {
+		if (*dev->dma_mask >= DMA_BIT_MASK(32)) {
+			dev_err(dev,
+				"%s: overflow %llx+%zu of device mask %llx\n",
+				caller, (long long)dma_addr, size,
+				(long long)*dev->dma_mask);
+		}
+		return false;
+	}
+	return true;
+}
+
 static void *dma_direct_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
@@ -31,7 +49,11 @@ static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
 		unsigned long offset, size_t size, enum dma_data_direction dir,
 		unsigned long attrs)
 {
-	return phys_to_dma(dev, page_to_phys(page)) + offset;
+	dma_addr_t dma_addr = phys_to_dma(dev, page_to_phys(page)) + offset;
+
+	if (!check_addr(dev, dma_addr, size, __func__))
+		return DIRECT_MAPPING_ERROR;
+	return dma_addr;
 }
 
 static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
@@ -44,17 +66,25 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 		BUG_ON(!sg_page(sg));
 
 		sg_dma_address(sg) = phys_to_dma(dev, sg_phys(sg));
+		if (!check_addr(dev, sg_dma_address(sg), sg->length, __func__))
+			return 0;
 		sg_dma_len(sg) = sg->length;
 	}
 
 	return nents;
 }
 
+static int dma_direct_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return dma_addr == DIRECT_MAPPING_ERROR;
+}
+
 const struct dma_map_ops dma_direct_ops = {
 	.alloc			= dma_direct_alloc,
 	.free			= dma_direct_free,
 	.map_page		= dma_direct_map_page,
 	.map_sg			= dma_direct_map_sg,
+	.mapping_error		= dma_direct_mapping_error,
 	.is_phys		= true,
 };
 EXPORT_SYMBOL(dma_direct_ops);
Signature · 1 line
2.14.2
#88 lore raw

PATCH 28/67 dma-direct: add support for CMA allocation

In reply to Christoph Hellwig

Try the CMA allocator for coherent allocations if supported.

Roughly modelled after the x86 code.

---
 lib/dma-direct.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)
lib/dma-direct.c +18 -6
index ddd9dcf4e663..d0266b39788b 100644
@@ -7,6 +7,7 @@
 #include <linux/mm.h>
 #include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
+#include <linux/dma-contiguous.h>
 #include <linux/pfn.h>
 
 #define DIRECT_MAPPING_ERROR		0
@@ -30,19 +31,30 @@ check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
 static void *dma_direct_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
-	void *ret;
+	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+	int page_order = get_order(size);
+	struct page *page = NULL;
 
-	ret = (void *)__get_free_pages(gfp, get_order(size));
-	if (ret)
-		*dma_handle = phys_to_dma(dev, virt_to_phys(ret));
+	/* CMA can be used only in the context which permits sleeping */
+	if (gfpflags_allow_blocking(gfp))
+		page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
+	if (!page)
+		page = alloc_pages(gfp, page_order);
+	if (!page)
+		return NULL;
 
-	return ret;
+	*dma_handle = phys_to_dma(dev, page_to_phys(page));
+	memset(page_address(page), 0, size);
+	return page_address(page);
 }
 
 static void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
 		dma_addr_t dma_addr, unsigned long attrs)
 {
-	free_pages((unsigned long)cpu_addr, get_order(size));
+	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+	if (!dma_release_from_contiguous(dev, virt_to_page(cpu_addr), count))
+		free_pages((unsigned long)cpu_addr, get_order(size));
 }
 
 static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
Signature · 1 line
2.14.2
#89 lore raw

PATCH 28/67 dma-direct: add support for CMA allocation

In reply to Christoph Hellwig

Try the CMA allocator for coherent allocations if supported.

Roughly modelled after the x86 code.

---
 lib/dma-direct.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)
lib/dma-direct.c +18 -6
index ddd9dcf4e663..d0266b39788b 100644
@@ -7,6 +7,7 @@
 #include <linux/mm.h>
 #include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
+#include <linux/dma-contiguous.h>
 #include <linux/pfn.h>
 
 #define DIRECT_MAPPING_ERROR		0
@@ -30,19 +31,30 @@ check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
 static void *dma_direct_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
-	void *ret;
+	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+	int page_order = get_order(size);
+	struct page *page = NULL;
 
-	ret = (void *)__get_free_pages(gfp, get_order(size));
-	if (ret)
-		*dma_handle = phys_to_dma(dev, virt_to_phys(ret));
+	/* CMA can be used only in the context which permits sleeping */
+	if (gfpflags_allow_blocking(gfp))
+		page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
+	if (!page)
+		page = alloc_pages(gfp, page_order);
+	if (!page)
+		return NULL;
 
-	return ret;
+	*dma_handle = phys_to_dma(dev, page_to_phys(page));
+	memset(page_address(page), 0, size);
+	return page_address(page);
 }
 
 static void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
 		dma_addr_t dma_addr, unsigned long attrs)
 {
-	free_pages((unsigned long)cpu_addr, get_order(size));
+	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+	if (!dma_release_from_contiguous(dev, virt_to_page(cpu_addr), count))
+		free_pages((unsigned long)cpu_addr, get_order(size));
 }
 
 static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
Signature · 1 line
2.14.2
#90 lore raw

PATCH 29/67 dma-direct: use node local allocations for coherent memory

In reply to Christoph Hellwig
---
 lib/dma-direct.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
lib/dma-direct.c +1 -1
index d0266b39788b..ab81de3ac1d3 100644
@@ -39,7 +39,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 	if (gfpflags_allow_blocking(gfp))
 		page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
 	if (!page)
-		page = alloc_pages(gfp, page_order);
+		page = alloc_pages_node(dev_to_node(dev), gfp, page_order);
 	if (!page)
 		return NULL;
 
Signature · 1 line
2.14.2
#91 lore raw

Re: [PATCH 29/67] dma-direct: use node local allocations for coherent memory

Missing patch description explaining why this change is desirable.

lib/dma-direct.c static void *dma_direct_alloc(struct device *dev, size_t size, · line 45

Quoted 11 lines · Christoph Hellwig
lib/dma-direct.c +1 -1
@@ -39,7 +39,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
        if (gfpflags_allow_blocking(gfp))
                page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
        if (!page)
-               page = alloc_pages(gfp, page_order);
+               page = alloc_pages_node(dev_to_node(dev), gfp, page_order);
        if (!page)
                return NULL;
 

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#92 lore raw

Re: [PATCH 29/67] dma-direct: use node local allocations for coherent memory

In reply to Christoph Hellwig

Missing patch description explaining why this change is desirable.

lib/dma-direct.c static void *dma_direct_alloc(struct device *dev, size_t size, · line 45

Quoted 11 lines · Christoph Hellwig
lib/dma-direct.c +1 -1
@@ -39,7 +39,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
        if (gfpflags_allow_blocking(gfp))
                page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
        if (!page)
-               page = alloc_pages(gfp, page_order);
+               page = alloc_pages_node(dev_to_node(dev), gfp, page_order);
        if (!page)
                return NULL;
 

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#93 lore raw

PATCH 29/67 dma-direct: use node local allocations for coherent memory

In reply to Christoph Hellwig
---
 lib/dma-direct.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
lib/dma-direct.c +1 -1
index d0266b39788b..ab81de3ac1d3 100644
@@ -39,7 +39,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 	if (gfpflags_allow_blocking(gfp))
 		page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
 	if (!page)
-		page = alloc_pages(gfp, page_order);
+		page = alloc_pages_node(dev_to_node(dev), gfp, page_order);
 	if (!page)
 		return NULL;
 
Signature · 1 line
2.14.2
#94 lore raw

PATCH 30/67 dma-direct: retry allocations using GFP_DMA for small masks

In reply to Christoph Hellwig

If we got back an allocation that wasn't inside the support coherent mask, retry the allocation using GFP_DMA.

Based on the x86 code.

---
 lib/dma-direct.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)
lib/dma-direct.c +24 -1
index ab81de3ac1d3..f8467cb3d89a 100644
@@ -28,6 +28,11 @@ check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
 	return true;
 }
 
+static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
+{
+	return phys_to_dma(dev, phys) + size <= dev->coherent_dma_mask;
+}
+
 static void *dma_direct_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
@@ -35,11 +40,29 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 	int page_order = get_order(size);
 	struct page *page = NULL;
 
+again:
 	/* CMA can be used only in the context which permits sleeping */
-	if (gfpflags_allow_blocking(gfp))
+	if (gfpflags_allow_blocking(gfp)) {
 		page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
+		if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+			dma_release_from_contiguous(dev, page, count);
+			page = NULL;
+		}
+	}
 	if (!page)
 		page = alloc_pages_node(dev_to_node(dev), gfp, page_order);
+
+	if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+		__free_pages(page, page_order);
+		page = NULL;
+
+		if (dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
+		    !(gfp & GFP_DMA)) {
+			gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
+			goto again;
+		}
+	}
+
 	if (!page)
 		return NULL;
 
Signature · 1 line
2.14.2
#95 lore raw

Re: [PATCH 30/67] dma-direct: retry allocations using GFP_DMA for small masks

Quoted 15 lines · Christoph Hellwig

If we got back an allocation that wasn't inside the support coherent mask, retry the allocation using GFP_DMA.

Based on the x86 code.

---
 lib/dma-direct.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)
lib/dma-direct.c +0 -0
index ab81de3ac1d3..f8467cb3d89a 100644

lib/dma-direct.c check_addr(struct device *dev, dma_addr_t dma_addr, size_t size, · line 33

Quoted 6 lines
lib/dma-direct.c +3 -0
@@ -28,6 +28,11 @@ check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
 	return true;
 }
 
+static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
+{
+	return phys_to_dma(dev, phys) + size <= dev->coherent_dma_mask;

Shouldn't it be: phys_to_dma(dev, phys) + size - 1 <= dev->coherent_dma_mask ?

Quoted 20 lines
lib/dma-direct.c +9 -1
+}
+
 static void *dma_direct_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
@@ -35,11 +40,29 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 	int page_order = get_order(size);
 	struct page *page = NULL;
 
+again:
 	/* CMA can be used only in the context which permits sleeping */
-	if (gfpflags_allow_blocking(gfp))
+	if (gfpflags_allow_blocking(gfp)) {
 		page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
+		if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+			dma_release_from_contiguous(dev, page, count);
+			page = NULL;
+		}
+	}
 	if (!page)

lib/dma-direct.c static void *dma_direct_alloc(struct device *dev, size_t size, · line 62

Quoted 10 lines
lib/dma-direct.c +9 -0
 		page = alloc_pages_node(dev_to_node(dev), gfp, page_order);
+
+	if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+		__free_pages(page, page_order);
+		page = NULL;
+
+		if (dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
+		    !(gfp & GFP_DMA)) {
+			gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
+			goto again;

Shouldn't we limit number of attempts?

Thanks
Vladimir

#96 lore raw

Re: [PATCH 30/67] dma-direct: retry allocations using GFP_DMA for small masks

Quoted 19 lines · Vladimir Murzin
Quoted 18 lines · Christoph Hellwig

If we got back an allocation that wasn't inside the support coherent mask, retry the allocation using GFP_DMA.

Based on the x86 code.

---
 lib/dma-direct.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)
lib/dma-direct.c +0 -0
index ab81de3ac1d3..f8467cb3d89a 100644
@@ -28,6 +28,11 @@ check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
 	return true;
 }
 
Quoted 5 lines

lib/dma-direct.c check_addr(struct device *dev, dma_addr_t dma_addr, size_t size, · line 33

Quoted 3 lines
lib/dma-direct.c +3 -0
+static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
+{
+	return phys_to_dma(dev, phys) + size <= dev->coherent_dma_mask;

Shouldn't it be: phys_to_dma(dev, phys) + size - 1 <= dev->coherent_dma_mask ?

Yes, I think it should. The existing code was blindly copy and pasted from x86.

Quoted 10 lines

lib/dma-direct.c static void *dma_direct_alloc(struct device *dev, size_t size, · line 62

Quoted 8 lines
lib/dma-direct.c +8 -0
+	if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+		__free_pages(page, page_order);
+		page = NULL;
+
+		if (dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
+		    !(gfp & GFP_DMA)) {
+			gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
+			goto again;

Shouldn't we limit number of attempts?

We only retty once anyway, due to the !GFP_DMA check first and then ORing in GFP_DMA.

#97 lore raw

Re: [PATCH 30/67] dma-direct: retry allocations using GFP_DMA for small masks

In reply to Vladimir Murzin
Quoted 19 lines · Vladimir Murzin
Quoted 18 lines · Christoph Hellwig

If we got back an allocation that wasn't inside the support coherent mask, retry the allocation using GFP_DMA.

Based on the x86 code.

---
 lib/dma-direct.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)
lib/dma-direct.c +0 -0
index ab81de3ac1d3..f8467cb3d89a 100644
@@ -28,6 +28,11 @@ check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
 	return true;
 }
 
Quoted 5 lines

lib/dma-direct.c check_addr(struct device *dev, dma_addr_t dma_addr, size_t size, · line 33

Quoted 3 lines
lib/dma-direct.c +3 -0
+static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
+{
+	return phys_to_dma(dev, phys) + size <= dev->coherent_dma_mask;

Shouldn't it be: phys_to_dma(dev, phys) + size - 1 <= dev->coherent_dma_mask ?

Yes, I think it should. The existing code was blindly copy and pasted from x86.

Quoted 10 lines

lib/dma-direct.c static void *dma_direct_alloc(struct device *dev, size_t size, · line 62

Quoted 8 lines
lib/dma-direct.c +8 -0
+	if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+		__free_pages(page, page_order);
+		page = NULL;
+
+		if (dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
+		    !(gfp & GFP_DMA)) {
+			gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
+			goto again;

Shouldn't we limit number of attempts?

We only retty once anyway, due to the !GFP_DMA check first and then ORing in GFP_DMA.

#98 lore raw

PATCH 30/67 dma-direct: retry allocations using GFP_DMA for small masks

In reply to Christoph Hellwig

If we got back an allocation that wasn't inside the support coherent mask, retry the allocation using GFP_DMA.

Based on the x86 code.

---
 lib/dma-direct.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)
lib/dma-direct.c +24 -1
index ab81de3ac1d3..f8467cb3d89a 100644
@@ -28,6 +28,11 @@ check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
 	return true;
 }
 
+static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
+{
+	return phys_to_dma(dev, phys) + size <= dev->coherent_dma_mask;
+}
+
 static void *dma_direct_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
@@ -35,11 +40,29 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 	int page_order = get_order(size);
 	struct page *page = NULL;
 
+again:
 	/* CMA can be used only in the context which permits sleeping */
-	if (gfpflags_allow_blocking(gfp))
+	if (gfpflags_allow_blocking(gfp)) {
 		page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
+		if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+			dma_release_from_contiguous(dev, page, count);
+			page = NULL;
+		}
+	}
 	if (!page)
 		page = alloc_pages_node(dev_to_node(dev), gfp, page_order);
+
+	if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+		__free_pages(page, page_order);
+		page = NULL;
+
+		if (dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
+		    !(gfp & GFP_DMA)) {
+			gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
+			goto again;
+		}
+	}
+
 	if (!page)
 		return NULL;
 
Signature · 1 line
2.14.2
#99 lore raw

PATCH 31/67 dma-direct: make dma_direct_{alloc,free} available to other implementations

In reply to Christoph Hellwig

So that they don't need to indirect through the operation vector.

---
 arch/arm/mm/dma-mapping-nommu.c | 9 +++------
 include/linux/dma-direct.h      | 5 +++++
 lib/dma-direct.c                | 6 +++---
 3 files changed, 11 insertions(+), 9 deletions(-)
arch/arm/mm/dma-mapping-nommu.c +3 -6
index 49e9831dc0f1..b4cf3e4e9d4a 100644
@@ -11,7 +11,7 @@
 
 #include <linux/export.h>
 #include <linux/mm.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
 
 #include <asm/cachetype.h>
@@ -39,7 +39,6 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 				 unsigned long attrs)
 
 {
-	const struct dma_map_ops *ops = &dma_direct_ops;
 	void *ret;
 
 	/*
@@ -48,7 +47,7 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 	 */
 
 	if (attrs & DMA_ATTR_NON_CONSISTENT)
-		return ops->alloc(dev, size, dma_handle, gfp, attrs);
+		return dma_direct_alloc(dev, size, dma_handle, gfp, attrs);
 
 	ret = dma_alloc_from_global_coherent(size, dma_handle);
 
@@ -70,10 +69,8 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr,
 			       unsigned long attrs)
 {
-	const struct dma_map_ops *ops = &dma_direct_ops;
-
 	if (attrs & DMA_ATTR_NON_CONSISTENT) {
-		ops->free(dev, size, cpu_addr, dma_addr, attrs);
+		dma_direct_free(dev, size, cpu_addr, dma_addr, attrs);
 	} else {
 		int ret = dma_release_from_global_coherent(get_order(size),
 							   cpu_addr);
include/linux/dma-direct.h +5 -0
index 10e924b7cba7..4788bf0bf683 100644
@@ -38,4 +38,9 @@ static inline void dma_mark_clean(void *addr, size_t size)
 }
 #endif /* CONFIG_ARCH_HAS_DMA_MARK_CLEAN */
 
+void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		gfp_t gfp, unsigned long attrs);
+void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+		dma_addr_t dma_addr, unsigned long attrs);
+
 #endif /* _LINUX_DMA_DIRECT_H */
lib/dma-direct.c +3 -3
index f8467cb3d89a..7e913728e099 100644
@@ -33,8 +33,8 @@ static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
 	return phys_to_dma(dev, phys) + size <= dev->coherent_dma_mask;
 }
 
-static void *dma_direct_alloc(struct device *dev, size_t size,
-		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
+void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		gfp_t gfp, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	int page_order = get_order(size);
@@ -71,7 +71,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 	return page_address(page);
 }
 
-static void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
 		dma_addr_t dma_addr, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
Signature · 1 line
2.14.2
Reviewed-by on v1 31/67
#100 lore raw

Re: [PATCH 31/67] dma-direct: make dma_direct_{alloc, free} available to other implementations

Quoted 82 lines · Christoph Hellwig

So that they don't need to indirect through the operation vector.

---
 arch/arm/mm/dma-mapping-nommu.c | 9 +++------
 include/linux/dma-direct.h      | 5 +++++
 lib/dma-direct.c                | 6 +++---
 3 files changed, 11 insertions(+), 9 deletions(-)
arch/arm/mm/dma-mapping-nommu.c +3 -6
index 49e9831dc0f1..b4cf3e4e9d4a 100644
@@ -11,7 +11,7 @@
 
 #include <linux/export.h>
 #include <linux/mm.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
 
 #include <asm/cachetype.h>
@@ -39,7 +39,6 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 				 unsigned long attrs)
 
 {
-	const struct dma_map_ops *ops = &dma_direct_ops;
 	void *ret;
 
 	/*
@@ -48,7 +47,7 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 	 */
 
 	if (attrs & DMA_ATTR_NON_CONSISTENT)
-		return ops->alloc(dev, size, dma_handle, gfp, attrs);
+		return dma_direct_alloc(dev, size, dma_handle, gfp, attrs);
 
 	ret = dma_alloc_from_global_coherent(size, dma_handle);
 
@@ -70,10 +69,8 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr,
 			       unsigned long attrs)
 {
-	const struct dma_map_ops *ops = &dma_direct_ops;
-
 	if (attrs & DMA_ATTR_NON_CONSISTENT) {
-		ops->free(dev, size, cpu_addr, dma_addr, attrs);
+		dma_direct_free(dev, size, cpu_addr, dma_addr, attrs);
 	} else {
 		int ret = dma_release_from_global_coherent(get_order(size),
 							   cpu_addr);
include/linux/dma-direct.h +5 -0
index 10e924b7cba7..4788bf0bf683 100644
@@ -38,4 +38,9 @@ static inline void dma_mark_clean(void *addr, size_t size)
 }
 #endif /* CONFIG_ARCH_HAS_DMA_MARK_CLEAN */
 
+void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		gfp_t gfp, unsigned long attrs);
+void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+		dma_addr_t dma_addr, unsigned long attrs);
+
 #endif /* _LINUX_DMA_DIRECT_H */
lib/dma-direct.c +2 -2
index f8467cb3d89a..7e913728e099 100644
@@ -33,8 +33,8 @@ static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
 	return phys_to_dma(dev, phys) + size <= dev->coherent_dma_mask;
 }
 
-static void *dma_direct_alloc(struct device *dev, size_t size,
-		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
+void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		gfp_t gfp, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	int page_order = get_order(size);

lib/dma-direct.c static void *dma_direct_alloc(struct device *dev, size_t size, · line 77

Quoted 8 lines
lib/dma-direct.c +1 -1
@@ -71,7 +71,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 	return page_address(page);
 }
 
-static void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
 		dma_addr_t dma_addr, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;

Thanks
Vladimir

#101 lore raw

PATCH 31/67 dma-direct: make dma_direct_{alloc,free} available to other implementations

In reply to Christoph Hellwig

So that they don't need to indirect through the operation vector.

---
 arch/arm/mm/dma-mapping-nommu.c | 9 +++------
 include/linux/dma-direct.h      | 5 +++++
 lib/dma-direct.c                | 6 +++---
 3 files changed, 11 insertions(+), 9 deletions(-)
arch/arm/mm/dma-mapping-nommu.c +3 -6
index 49e9831dc0f1..b4cf3e4e9d4a 100644
@@ -11,7 +11,7 @@
 
 #include <linux/export.h>
 #include <linux/mm.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/scatterlist.h>
 
 #include <asm/cachetype.h>
@@ -39,7 +39,6 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 				 unsigned long attrs)
 
 {
-	const struct dma_map_ops *ops = &dma_direct_ops;
 	void *ret;
 
 	/*
@@ -48,7 +47,7 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
 	 */
 
 	if (attrs & DMA_ATTR_NON_CONSISTENT)
-		return ops->alloc(dev, size, dma_handle, gfp, attrs);
+		return dma_direct_alloc(dev, size, dma_handle, gfp, attrs);
 
 	ret = dma_alloc_from_global_coherent(size, dma_handle);
 
@@ -70,10 +69,8 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
 			       void *cpu_addr, dma_addr_t dma_addr,
 			       unsigned long attrs)
 {
-	const struct dma_map_ops *ops = &dma_direct_ops;
-
 	if (attrs & DMA_ATTR_NON_CONSISTENT) {
-		ops->free(dev, size, cpu_addr, dma_addr, attrs);
+		dma_direct_free(dev, size, cpu_addr, dma_addr, attrs);
 	} else {
 		int ret = dma_release_from_global_coherent(get_order(size),
 							   cpu_addr);
include/linux/dma-direct.h +5 -0
index 10e924b7cba7..4788bf0bf683 100644
@@ -38,4 +38,9 @@ static inline void dma_mark_clean(void *addr, size_t size)
 }
 #endif /* CONFIG_ARCH_HAS_DMA_MARK_CLEAN */
 
+void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		gfp_t gfp, unsigned long attrs);
+void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+		dma_addr_t dma_addr, unsigned long attrs);
+
 #endif /* _LINUX_DMA_DIRECT_H */
lib/dma-direct.c +3 -3
index f8467cb3d89a..7e913728e099 100644
@@ -33,8 +33,8 @@ static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
 	return phys_to_dma(dev, phys) + size <= dev->coherent_dma_mask;
 }
 
-static void *dma_direct_alloc(struct device *dev, size_t size,
-		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
+void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		gfp_t gfp, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	int page_order = get_order(size);
@@ -71,7 +71,7 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
 	return page_address(page);
 }
 
-static void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
 		dma_addr_t dma_addr, unsigned long attrs)
 {
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
Signature · 1 line
2.14.2
#102 lore raw

PATCH 32/67 dma-direct: add support for allocation from ZONE_DMA and ZONE_DMA32

In reply to Christoph Hellwig
---
 lib/dma-direct.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
lib/dma-direct.c +14 -0
index 7e913728e099..2e9b9494610c 100644
@@ -12,6 +12,14 @@
 
 #define DIRECT_MAPPING_ERROR		0
 
+/*
+ * Most architectures use ZONE_DMA for the first 16 Megabytes, but
+ * some use it for entirely different regions:
+ */
+#ifndef ARCH_ZONE_DMA_BITS
+#define ARCH_ZONE_DMA_BITS 24
+#endif
+
 static bool
 check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
 		const char *caller)
@@ -40,6 +48,12 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 	int page_order = get_order(size);
 	struct page *page = NULL;
 
+	/* GFP_DMA32 and GFP_DMA are no ops without the corresponding zones: */
+	if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
+		gfp |= GFP_DMA32;
+	else if (dev->coherent_dma_mask < DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
+		gfp |= GFP_DMA;
+
 again:
 	/* CMA can be used only in the context which permits sleeping */
 	if (gfpflags_allow_blocking(gfp)) {
Signature · 1 line
2.14.2
#103 lore raw

PATCH 32/67 dma-direct: add support for allocation from ZONE_DMA and ZONE_DMA32

In reply to Christoph Hellwig
---
 lib/dma-direct.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
lib/dma-direct.c +14 -0
index 7e913728e099..2e9b9494610c 100644
@@ -12,6 +12,14 @@
 
 #define DIRECT_MAPPING_ERROR		0
 
+/*
+ * Most architectures use ZONE_DMA for the first 16 Megabytes, but
+ * some use it for entirely different regions:
+ */
+#ifndef ARCH_ZONE_DMA_BITS
+#define ARCH_ZONE_DMA_BITS 24
+#endif
+
 static bool
 check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
 		const char *caller)
@@ -40,6 +48,12 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 	int page_order = get_order(size);
 	struct page *page = NULL;
 
+	/* GFP_DMA32 and GFP_DMA are no ops without the corresponding zones: */
+	if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
+		gfp |= GFP_DMA32;
+	else if (dev->coherent_dma_mask < DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
+		gfp |= GFP_DMA;
+
 again:
 	/* CMA can be used only in the context which permits sleeping */
 	if (gfpflags_allow_blocking(gfp)) {
Signature · 1 line
2.14.2
#104 lore raw

PATCH 33/67 dma-direct: reject too small dma masks

In reply to Christoph Hellwig
---
 include/linux/dma-direct.h |  1 +
 lib/dma-direct.c           | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
include/linux/dma-direct.h +1 -0
index 4788bf0bf683..bcdb1a3e4b1f 100644
@@ -42,5 +42,6 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		gfp_t gfp, unsigned long attrs);
 void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
 		dma_addr_t dma_addr, unsigned long attrs);
+int dma_direct_supported(struct device *dev, u64 mask);
 
 #endif /* _LINUX_DMA_DIRECT_H */
lib/dma-direct.c +19 -0
index 2e9b9494610c..5bb289483efc 100644
@@ -123,6 +123,24 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	return nents;
 }
 
+int dma_direct_supported(struct device *dev, u64 mask)
+{
+#ifdef CONFIG_ZONE_DMA
+	if (mask < DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
+		return 0;
+#else
+	/*
+	 * Because 32-bit DMA masks are so common we expect every architecture
+	 * to be able to satisfy them - either by not supporting more physical
+	 * memory, or by providing a ZONE_DMA32.  If neither is the case, the
+	 * architecture needs to use an IOMMU instead of the direct mapping.
+	 */
+	if (mask < DMA_BIT_MASK(32))
+		return 0;
+#endif
+	return 1;
+}
+
 static int dma_direct_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
 	return dma_addr == DIRECT_MAPPING_ERROR;
@@ -133,6 +151,7 @@ const struct dma_map_ops dma_direct_ops = {
 	.free			= dma_direct_free,
 	.map_page		= dma_direct_map_page,
 	.map_sg			= dma_direct_map_sg,
+	.dma_supported		= dma_direct_supported,
 	.mapping_error		= dma_direct_mapping_error,
 	.is_phys		= true,
 };
Signature · 1 line
2.14.2
#105 lore raw

PATCH 33/67 dma-direct: reject too small dma masks

In reply to Christoph Hellwig
---
 include/linux/dma-direct.h |  1 +
 lib/dma-direct.c           | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
include/linux/dma-direct.h +1 -0
index 4788bf0bf683..bcdb1a3e4b1f 100644
@@ -42,5 +42,6 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		gfp_t gfp, unsigned long attrs);
 void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
 		dma_addr_t dma_addr, unsigned long attrs);
+int dma_direct_supported(struct device *dev, u64 mask);
 
 #endif /* _LINUX_DMA_DIRECT_H */
lib/dma-direct.c +19 -0
index 2e9b9494610c..5bb289483efc 100644
@@ -123,6 +123,24 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	return nents;
 }
 
+int dma_direct_supported(struct device *dev, u64 mask)
+{
+#ifdef CONFIG_ZONE_DMA
+	if (mask < DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
+		return 0;
+#else
+	/*
+	 * Because 32-bit DMA masks are so common we expect every architecture
+	 * to be able to satisfy them - either by not supporting more physical
+	 * memory, or by providing a ZONE_DMA32.  If neither is the case, the
+	 * architecture needs to use an IOMMU instead of the direct mapping.
+	 */
+	if (mask < DMA_BIT_MASK(32))
+		return 0;
+#endif
+	return 1;
+}
+
 static int dma_direct_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
 	return dma_addr == DIRECT_MAPPING_ERROR;
@@ -133,6 +151,7 @@ const struct dma_map_ops dma_direct_ops = {
 	.free			= dma_direct_free,
 	.map_page		= dma_direct_map_page,
 	.map_sg			= dma_direct_map_sg,
+	.dma_supported		= dma_direct_supported,
 	.mapping_error		= dma_direct_mapping_error,
 	.is_phys		= true,
 };
Signature · 1 line
2.14.2
#106 lore raw

PATCH 34/67 cris: use dma-direct

In reply to Christoph Hellwig

cris currently has an incomplete direct mapping dma_map_ops implementation is PCI support is enabled. Replace it with the fully feature generic dma-direct implementation.

---
 arch/cris/Kconfig                       |  4 ++
 arch/cris/arch-v32/drivers/pci/Makefile |  2 +-
 arch/cris/arch-v32/drivers/pci/dma.c    | 78 ---------------------------------
 arch/cris/include/asm/Kbuild            |  1 +
 arch/cris/include/asm/dma-mapping.h     | 20 ---------
 5 files changed, 6 insertions(+), 99 deletions(-)
 delete mode 100644 arch/cris/arch-v32/drivers/pci/dma.c
 delete mode 100644 arch/cris/include/asm/dma-mapping.h
arch/cris/Kconfig +4 -0
index 54d3f426763b..cd5a0865c97f 100644
@@ -33,6 +33,9 @@ config GENERIC_CALIBRATE_DELAY
 config NO_IOPORT_MAP
 	def_bool y if !PCI
 
+config NO_DMA
+	def_bool y if !PCI
+
 config FORCE_MAX_ZONEORDER
 	int
 	default 6
@@ -72,6 +75,7 @@ config CRIS
 	select GENERIC_SCHED_CLOCK if ETRAX_ARCH_V32
 	select HAVE_DEBUG_BUGVERBOSE if ETRAX_ARCH_V32
 	select HAVE_NMI
+	select DMA_DIRECT_OPS if PCI
 
 config HZ
 	int
arch/cris/arch-v32/drivers/pci/Makefile +1 -1
index bff7482f2444..93c8be6170b1 100644
@@ -2,4 +2,4 @@
 # Makefile for Etrax cardbus driver
 #
 
-obj-$(CONFIG_ETRAX_CARDBUS)        += bios.o dma.o
+obj-$(CONFIG_ETRAX_CARDBUS)        += bios.o
arch/cris/arch-v32/drivers/pci/dma.c deleted +0 -78

78 lines not on this page · raw message

arch/cris/include/asm/Kbuild +1 -0
index 460349cb147f..8cf45ac30c1b 100644
@@ -5,6 +5,7 @@ generic-y += cmpxchg.h
 generic-y += current.h
 generic-y += device.h
 generic-y += div64.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
 generic-y += extable.h
arch/cris/include/asm/dma-mapping.h deleted +0 -20
deleted file mode 100644
index 1553bdb30a0c..000000000000
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_CRIS_DMA_MAPPING_H
-#define _ASM_CRIS_DMA_MAPPING_H
-
-#ifdef CONFIG_PCI
-extern const struct dma_map_ops v32_dma_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &v32_dma_ops;
-}
-#else
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	BUG();
-	return NULL;
-}
-#endif
-
-#endif
Signature · 1 line
2.14.2
Acked-by on v1 34/67
#107 lore raw

Re: [PATCH 34/67] cris: use dma-direct

Quoted 5 lines · Christoph Hellwig

cris currently has an incomplete direct mapping dma_map_ops implementation is PCI support is enabled. Replace it with the fully feature generic dma-direct implementation.

For CRIS:

Quoted 10 lines
---
 arch/cris/Kconfig                       |  4 ++
 arch/cris/arch-v32/drivers/pci/Makefile |  2 +-
 arch/cris/arch-v32/drivers/pci/dma.c    | 78 ---------------------------------
 arch/cris/include/asm/Kbuild            |  1 +
 arch/cris/include/asm/dma-mapping.h     | 20 ---------
 5 files changed, 6 insertions(+), 99 deletions(-)
 delete mode 100644 arch/cris/arch-v32/drivers/pci/dma.c
 delete mode 100644 arch/cris/include/asm/dma-mapping.h

/^JN - Jesper Nilsson

Signature · 1 line
               Jesper Nilsson -- [email protected]
#108 lore raw

PATCH 34/67 cris: use dma-direct

In reply to Christoph Hellwig

cris currently has an incomplete direct mapping dma_map_ops implementation is PCI support is enabled. Replace it with the fully feature generic dma-direct implementation.

---
 arch/cris/Kconfig                       |  4 ++
 arch/cris/arch-v32/drivers/pci/Makefile |  2 +-
 arch/cris/arch-v32/drivers/pci/dma.c    | 78 ---------------------------------
 arch/cris/include/asm/Kbuild            |  1 +
 arch/cris/include/asm/dma-mapping.h     | 20 ---------
 5 files changed, 6 insertions(+), 99 deletions(-)
 delete mode 100644 arch/cris/arch-v32/drivers/pci/dma.c
 delete mode 100644 arch/cris/include/asm/dma-mapping.h
arch/cris/Kconfig +4 -0
index 54d3f426763b..cd5a0865c97f 100644
@@ -33,6 +33,9 @@ config GENERIC_CALIBRATE_DELAY
 config NO_IOPORT_MAP
 	def_bool y if !PCI
 
+config NO_DMA
+	def_bool y if !PCI
+
 config FORCE_MAX_ZONEORDER
 	int
 	default 6
@@ -72,6 +75,7 @@ config CRIS
 	select GENERIC_SCHED_CLOCK if ETRAX_ARCH_V32
 	select HAVE_DEBUG_BUGVERBOSE if ETRAX_ARCH_V32
 	select HAVE_NMI
+	select DMA_DIRECT_OPS if PCI
 
 config HZ
 	int
arch/cris/arch-v32/drivers/pci/Makefile +1 -1
index bff7482f2444..93c8be6170b1 100644
@@ -2,4 +2,4 @@
 # Makefile for Etrax cardbus driver
 #
 
-obj-$(CONFIG_ETRAX_CARDBUS)        += bios.o dma.o
+obj-$(CONFIG_ETRAX_CARDBUS)        += bios.o
arch/cris/arch-v32/drivers/pci/dma.c deleted +0 -78

78 lines not on this page · raw message

arch/cris/include/asm/Kbuild +1 -0
index 460349cb147f..8cf45ac30c1b 100644
@@ -5,6 +5,7 @@ generic-y += cmpxchg.h
 generic-y += current.h
 generic-y += device.h
 generic-y += div64.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
 generic-y += extable.h
arch/cris/include/asm/dma-mapping.h deleted +0 -20
deleted file mode 100644
index 1553bdb30a0c..000000000000
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_CRIS_DMA_MAPPING_H
-#define _ASM_CRIS_DMA_MAPPING_H
-
-#ifdef CONFIG_PCI
-extern const struct dma_map_ops v32_dma_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &v32_dma_ops;
-}
-#else
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	BUG();
-	return NULL;
-}
-#endif
-
-#endif
Signature · 1 line
2.14.2
#109 lore raw

PATCH 35/67 h8300: use dma-direct

In reply to Christoph Hellwig

Replace the bare-bones h8300 direct dma mapping implementation with the fully featured generic dma-direct one.

---
 arch/h8300/Kconfig                   |  1 +
 arch/h8300/include/asm/Kbuild        |  1 +
 arch/h8300/include/asm/dma-mapping.h | 12 -------
 arch/h8300/kernel/Makefile           |  2 +-
 arch/h8300/kernel/dma.c              | 67 ------------------------------------
 5 files changed, 3 insertions(+), 80 deletions(-)
 delete mode 100644 arch/h8300/include/asm/dma-mapping.h
 delete mode 100644 arch/h8300/kernel/dma.c
arch/h8300/Kconfig +1 -0
index f8d3fde08190..091d6d04b5e5 100644
@@ -23,6 +23,7 @@ config H8300
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_HASH
 	select CPU_NO_EFFICIENT_FFS
+	select DMA_DIRECT_OPS
 
 config CPU_BIG_ENDIAN
 	def_bool y
arch/h8300/include/asm/Kbuild +1 -0
index bc077491d299..642752c94306 100644
@@ -9,6 +9,7 @@ generic-y += delay.h
 generic-y += device.h
 generic-y += div64.h
 generic-y += dma.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
 generic-y += extable.h
arch/h8300/include/asm/dma-mapping.h deleted +0 -12
deleted file mode 100644
index 21bb1fc3a6f1..000000000000
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _H8300_DMA_MAPPING_H
-#define _H8300_DMA_MAPPING_H
-
-extern const struct dma_map_ops h8300_dma_map_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &h8300_dma_map_ops;
-}
-
-#endif
arch/h8300/kernel/Makefile +1 -1
index b62e830525c6..307aa51576dd 100644
@@ -7,7 +7,7 @@ extra-y := vmlinux.lds
 
 obj-y := process.o traps.o ptrace.o \
 	 signal.o setup.o syscalls.o \
-	 irq.o entry.o dma.o
+	 irq.o entry.o
 
 obj-$(CONFIG_ROMKERNEL) += head_rom.o
 obj-$(CONFIG_RAMKERNEL) += head_ram.o
arch/h8300/kernel/dma.c deleted +0 -67

67 lines not on this page · raw message

Signature · 1 line
2.14.2
#110 lore raw

PATCH 36/67 x86: remove dma_alloc_coherent_mask

In reply to Christoph Hellwig

These days all devices (including the ISA fallback device) have a coherent DMA mask set, so remove the workaround.

---
 arch/x86/include/asm/dma-mapping.h | 18 ++----------------
 arch/x86/kernel/pci-dma.c          | 10 ++++------
 arch/x86/mm/mem_encrypt.c          |  4 +---
 drivers/xen/swiotlb-xen.c          | 16 +---------------
 4 files changed, 8 insertions(+), 40 deletions(-)
arch/x86/include/asm/dma-mapping.h +2 -16
index 6277c83c0eb1..545bf3721bc0 100644
@@ -44,26 +44,12 @@ extern void dma_generic_free_coherent(struct device *dev, size_t size,
 				      void *vaddr, dma_addr_t dma_addr,
 				      unsigned long attrs);
 
-static inline unsigned long dma_alloc_coherent_mask(struct device *dev,
-						    gfp_t gfp)
-{
-	unsigned long dma_mask = 0;
-
-	dma_mask = dev->coherent_dma_mask;
-	if (!dma_mask)
-		dma_mask = (gfp & GFP_DMA) ? DMA_BIT_MASK(24) : DMA_BIT_MASK(32);
-
-	return dma_mask;
-}
-
 static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp)
 {
-	unsigned long dma_mask = dma_alloc_coherent_mask(dev, gfp);
-
-	if (dma_mask <= DMA_BIT_MASK(24))
+	if (dev->coherent_dma_mask <= DMA_BIT_MASK(24))
 		gfp |= GFP_DMA;
 #ifdef CONFIG_X86_64
-	if (dma_mask <= DMA_BIT_MASK(32) && !(gfp & GFP_DMA))
+	if (dev->coherent_dma_mask <= DMA_BIT_MASK(32) && !(gfp & GFP_DMA))
 		gfp |= GFP_DMA32;
 #endif
        return gfp;
arch/x86/kernel/pci-dma.c +4 -6
index df7ab02f959f..b59820872ec7 100644
@@ -80,13 +80,10 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 				 dma_addr_t *dma_addr, gfp_t flag,
 				 unsigned long attrs)
 {
-	unsigned long dma_mask;
 	struct page *page;
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	dma_addr_t addr;
 
-	dma_mask = dma_alloc_coherent_mask(dev, flag);
-
 again:
 	page = NULL;
 	/* CMA can be used only in the context which permits sleeping */
@@ -95,7 +92,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 						 flag);
 		if (page) {
 			addr = phys_to_dma(dev, page_to_phys(page));
-			if (addr + size > dma_mask) {
+			if (addr + size > dev->coherent_dma_mask) {
 				dma_release_from_contiguous(dev, page, count);
 				page = NULL;
 			}
@@ -108,10 +105,11 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 		return NULL;
 
 	addr = phys_to_dma(dev, page_to_phys(page));
-	if (addr + size > dma_mask) {
+	if (addr + size > dev->coherent_dma_mask) {
 		__free_pages(page, get_order(size));
 
-		if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) {
+		if (dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
+		    !(flag & GFP_DMA)) {
 			flag = (flag & ~GFP_DMA32) | GFP_DMA;
 			goto again;
 		}
arch/x86/mm/mem_encrypt.c +1 -3
index 764b916ef7da..479586b8ca9b 100644
@@ -203,12 +203,10 @@ void __init sme_early_init(void)
 static void *sev_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		       gfp_t gfp, unsigned long attrs)
 {
-	unsigned long dma_mask;
 	unsigned int order;
 	struct page *page;
 	void *vaddr = NULL;
 
-	dma_mask = dma_alloc_coherent_mask(dev, gfp);
 	order = get_order(size);
 
 	/*
@@ -226,7 +224,7 @@ static void *sev_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		 * mask with it already cleared.
 		 */
 		addr = __sme_clr(phys_to_dma(dev, page_to_phys(page)));
-		if ((addr + size) > dma_mask) {
+		if ((addr + size) > dev->coherent_dma_mask) {
 			__free_pages(page, get_order(size));
 		} else {
 			vaddr = page_address(page);
drivers/xen/swiotlb-xen.c +1 -15
index 5bb72d3f8337..e1c60899fdbc 100644
@@ -53,20 +53,6 @@
  * API.
  */
 
-#ifndef CONFIG_X86
-static unsigned long dma_alloc_coherent_mask(struct device *dev,
-					    gfp_t gfp)
-{
-	unsigned long dma_mask = 0;
-
-	dma_mask = dev->coherent_dma_mask;
-	if (!dma_mask)
-		dma_mask = (gfp & GFP_DMA) ? DMA_BIT_MASK(24) : DMA_BIT_MASK(32);
-
-	return dma_mask;
-}
-#endif
-
 #define XEN_SWIOTLB_ERROR_CODE	(~(dma_addr_t)0x0)
 
 static char *xen_io_tlb_start, *xen_io_tlb_end;
@@ -328,7 +314,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 		return ret;
 
 	if (hwdev && hwdev->coherent_dma_mask)
-		dma_mask = dma_alloc_coherent_mask(hwdev, flags);
+		dma_mask = hwdev->coherent_dma_mask;
 
 	/* At this point dma_handle is the physical address, next we are
 	 * going to set it to the machine address.
Signature · 1 line
2.14.2
#111 lore raw

PATCH 36/67 x86: remove dma_alloc_coherent_mask

In reply to Christoph Hellwig

These days all devices (including the ISA fallback device) have a coherent DMA mask set, so remove the workaround.

---
 arch/x86/include/asm/dma-mapping.h | 18 ++----------------
 arch/x86/kernel/pci-dma.c          | 10 ++++------
 arch/x86/mm/mem_encrypt.c          |  4 +---
 drivers/xen/swiotlb-xen.c          | 16 +---------------
 4 files changed, 8 insertions(+), 40 deletions(-)
arch/x86/include/asm/dma-mapping.h +2 -16
index 6277c83c0eb1..545bf3721bc0 100644
@@ -44,26 +44,12 @@ extern void dma_generic_free_coherent(struct device *dev, size_t size,
 				      void *vaddr, dma_addr_t dma_addr,
 				      unsigned long attrs);
 
-static inline unsigned long dma_alloc_coherent_mask(struct device *dev,
-						    gfp_t gfp)
-{
-	unsigned long dma_mask = 0;
-
-	dma_mask = dev->coherent_dma_mask;
-	if (!dma_mask)
-		dma_mask = (gfp & GFP_DMA) ? DMA_BIT_MASK(24) : DMA_BIT_MASK(32);
-
-	return dma_mask;
-}
-
 static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp)
 {
-	unsigned long dma_mask = dma_alloc_coherent_mask(dev, gfp);
-
-	if (dma_mask <= DMA_BIT_MASK(24))
+	if (dev->coherent_dma_mask <= DMA_BIT_MASK(24))
 		gfp |= GFP_DMA;
 #ifdef CONFIG_X86_64
-	if (dma_mask <= DMA_BIT_MASK(32) && !(gfp & GFP_DMA))
+	if (dev->coherent_dma_mask <= DMA_BIT_MASK(32) && !(gfp & GFP_DMA))
 		gfp |= GFP_DMA32;
 #endif
        return gfp;
arch/x86/kernel/pci-dma.c +4 -6
index df7ab02f959f..b59820872ec7 100644
@@ -80,13 +80,10 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 				 dma_addr_t *dma_addr, gfp_t flag,
 				 unsigned long attrs)
 {
-	unsigned long dma_mask;
 	struct page *page;
 	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	dma_addr_t addr;
 
-	dma_mask = dma_alloc_coherent_mask(dev, flag);
-
 again:
 	page = NULL;
 	/* CMA can be used only in the context which permits sleeping */
@@ -95,7 +92,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 						 flag);
 		if (page) {
 			addr = phys_to_dma(dev, page_to_phys(page));
-			if (addr + size > dma_mask) {
+			if (addr + size > dev->coherent_dma_mask) {
 				dma_release_from_contiguous(dev, page, count);
 				page = NULL;
 			}
@@ -108,10 +105,11 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 		return NULL;
 
 	addr = phys_to_dma(dev, page_to_phys(page));
-	if (addr + size > dma_mask) {
+	if (addr + size > dev->coherent_dma_mask) {
 		__free_pages(page, get_order(size));
 
-		if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) {
+		if (dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
+		    !(flag & GFP_DMA)) {
 			flag = (flag & ~GFP_DMA32) | GFP_DMA;
 			goto again;
 		}
arch/x86/mm/mem_encrypt.c +1 -3
index 764b916ef7da..479586b8ca9b 100644
@@ -203,12 +203,10 @@ void __init sme_early_init(void)
 static void *sev_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		       gfp_t gfp, unsigned long attrs)
 {
-	unsigned long dma_mask;
 	unsigned int order;
 	struct page *page;
 	void *vaddr = NULL;
 
-	dma_mask = dma_alloc_coherent_mask(dev, gfp);
 	order = get_order(size);
 
 	/*
@@ -226,7 +224,7 @@ static void *sev_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		 * mask with it already cleared.
 		 */
 		addr = __sme_clr(phys_to_dma(dev, page_to_phys(page)));
-		if ((addr + size) > dma_mask) {
+		if ((addr + size) > dev->coherent_dma_mask) {
 			__free_pages(page, get_order(size));
 		} else {
 			vaddr = page_address(page);
drivers/xen/swiotlb-xen.c +1 -15
index 5bb72d3f8337..e1c60899fdbc 100644
@@ -53,20 +53,6 @@
  * API.
  */
 
-#ifndef CONFIG_X86
-static unsigned long dma_alloc_coherent_mask(struct device *dev,
-					    gfp_t gfp)
-{
-	unsigned long dma_mask = 0;
-
-	dma_mask = dev->coherent_dma_mask;
-	if (!dma_mask)
-		dma_mask = (gfp & GFP_DMA) ? DMA_BIT_MASK(24) : DMA_BIT_MASK(32);
-
-	return dma_mask;
-}
-#endif
-
 #define XEN_SWIOTLB_ERROR_CODE	(~(dma_addr_t)0x0)
 
 static char *xen_io_tlb_start, *xen_io_tlb_end;
@@ -328,7 +314,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 		return ret;
 
 	if (hwdev && hwdev->coherent_dma_mask)
-		dma_mask = dma_alloc_coherent_mask(hwdev, flags);
+		dma_mask = hwdev->coherent_dma_mask;
 
 	/* At this point dma_handle is the physical address, next we are
 	 * going to set it to the machine address.
Signature · 1 line
2.14.2
#112 lore raw

PATCH 37/67 x86: use dma-direct

In reply to Christoph Hellwig

The generic dma-direct implementation is now functionally equivalent to the x86 nommu dma_map implementation, so switch over to using it.

Note that the various iommu drivers are switched from x86_dma_supported to dma_direct_supported to provide identical functionality, although the checks looks fairly questionable for at least some of them.

---
 arch/x86/Kconfig                   |  1 +
 arch/x86/include/asm/dma-mapping.h |  8 -----
 arch/x86/include/asm/iommu.h       |  3 --
 arch/x86/kernel/Makefile           |  2 +-
 arch/x86/kernel/amd_gart_64.c      |  7 ++--
 arch/x86/kernel/pci-calgary_64.c   |  3 +-
 arch/x86/kernel/pci-dma.c          | 66 +-------------------------------------
 arch/x86/kernel/pci-swiotlb.c      |  5 ++-
 arch/x86/pci/sta2x11-fixup.c       |  2 +-
 drivers/iommu/amd_iommu.c          |  7 ++--
 drivers/iommu/intel-iommu.c        |  3 +-
 11 files changed, 17 insertions(+), 90 deletions(-)
arch/x86/Kconfig +1 -0
index f6f4328103c0..55ad01515075 100644
@@ -83,6 +83,7 @@ config X86
 	select CLOCKSOURCE_VALIDATE_LAST_CYCLE
 	select CLOCKSOURCE_WATCHDOG
 	select DCACHE_WORD_ACCESS
+	select DMA_DIRECT_OPS
 	select EDAC_ATOMIC_SCRUB
 	select EDAC_SUPPORT
 	select GENERIC_CLOCKEVENTS
arch/x86/include/asm/dma-mapping.h +0 -8
index 545bf3721bc0..df9816b385eb 100644
@@ -36,14 +36,6 @@ int arch_dma_supported(struct device *dev, u64 mask);
 bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp);
 #define arch_dma_alloc_attrs arch_dma_alloc_attrs
 
-extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
-					dma_addr_t *dma_addr, gfp_t flag,
-					unsigned long attrs);
-
-extern void dma_generic_free_coherent(struct device *dev, size_t size,
-				      void *vaddr, dma_addr_t dma_addr,
-				      unsigned long attrs);
-
 static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp)
 {
 	if (dev->coherent_dma_mask <= DMA_BIT_MASK(24))
arch/x86/include/asm/iommu.h +0 -3
index 1e5d5d92eb40..baedab8ac538 100644
@@ -2,13 +2,10 @@
 #ifndef _ASM_X86_IOMMU_H
 #define _ASM_X86_IOMMU_H
 
-extern const struct dma_map_ops nommu_dma_ops;
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
 extern int iommu_pass_through;
 
-int x86_dma_supported(struct device *dev, u64 mask);
-
 /* 10 seconds */
 #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
 
arch/x86/kernel/Makefile +1 -1
index 81bb565f4497..beee4332e69b 100644
@@ -54,7 +54,7 @@ obj-$(CONFIG_X86_ESPFIX64)	+= espfix_64.o
 obj-$(CONFIG_SYSFS)	+= ksysfs.o
 obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o topology.o kdebugfs.o
-obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
+obj-y			+= alternative.o i8253.o hw_breakpoint.o
 obj-y			+= tsc.o tsc_msr.o io_delay.o rtc.o
 obj-y			+= pci-iommu_table.o
 obj-y			+= resource.o
arch/x86/kernel/amd_gart_64.c +3 -4
index ecd486cb06ab..52e3abcf3e70 100644
@@ -501,8 +501,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 		}
 		__free_pages(page, get_order(size));
 	} else
-		return dma_generic_alloc_coherent(dev, size, dma_addr, flag,
-						  attrs);
+		return dma_direct_alloc(dev, size, dma_addr, flag, attrs);
 
 	return NULL;
 }
@@ -513,7 +512,7 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr,
 		   dma_addr_t dma_addr, unsigned long attrs)
 {
 	gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, 0);
-	dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs);
+	dma_direct_free(dev, size, vaddr, dma_addr, attrs);
 }
 
 static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr)
@@ -705,7 +704,7 @@ static const struct dma_map_ops gart_dma_ops = {
 	.alloc				= gart_alloc_coherent,
 	.free				= gart_free_coherent,
 	.mapping_error			= gart_mapping_error,
-	.dma_supported			= x86_dma_supported,
+	.dma_supported			= dma_direct_supported,
 };
 
 static void gart_iommu_shutdown(void)
arch/x86/kernel/pci-calgary_64.c +2 -1
index 35c461f21815..5647853053bd 100644
@@ -33,6 +33,7 @@
 #include <linux/string.h>
 #include <linux/crash_dump.h>
 #include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/bitmap.h>
 #include <linux/pci_ids.h>
 #include <linux/pci.h>
@@ -493,7 +494,7 @@ static const struct dma_map_ops calgary_dma_ops = {
 	.map_page = calgary_map_page,
 	.unmap_page = calgary_unmap_page,
 	.mapping_error = calgary_mapping_error,
-	.dma_supported = x86_dma_supported,
+	.dma_supported = dma_direct_supported,
 };
 
 static inline void __iomem * busno_to_bbar(unsigned char num)
arch/x86/kernel/pci-dma.c +1 -65

84 lines not on this page · raw message

arch/x86/kernel/pci-swiotlb.c +2 -3
index 9d3e35c33d94..7a11a3e4f697 100644
@@ -30,8 +30,7 @@ void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 	 */
 	flags |= __GFP_NOWARN;
 
-	vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags,
-					   attrs);
+	vaddr = dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
 	if (vaddr)
 		return vaddr;
 
@@ -45,7 +44,7 @@ void x86_swiotlb_free_coherent(struct device *dev, size_t size,
 	if (is_swiotlb_buffer(dma_to_phys(dev, dma_addr)))
 		swiotlb_free_coherent(dev, size, vaddr, dma_addr);
 	else
-		dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs);
+		dma_direct_free(dev, size, vaddr, dma_addr, attrs);
 }
 
 static const struct dma_map_ops swiotlb_dma_ops = {
arch/x86/pci/sta2x11-fixup.c +1 -1
index 75577c1490c4..6c712fe11bdc 100644
@@ -193,7 +193,7 @@ static const struct dma_map_ops sta2x11_dma_ops = {
 	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
 	.sync_sg_for_device = swiotlb_sync_sg_for_device,
 	.mapping_error = swiotlb_dma_mapping_error,
-	.dma_supported = x86_dma_supported,
+	.dma_supported = dma_direct_supported,
 };
 
 /* At setup time, we use our own ops if the device is a ConneXt one */
drivers/iommu/amd_iommu.c +4 -3
index 7d5eb004091d..ea4734de5357 100644
@@ -28,6 +28,7 @@
 #include <linux/debugfs.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/iommu-helper.h>
 #include <linux/iommu.h>
 #include <linux/delay.h>
@@ -2182,7 +2183,7 @@ static int amd_iommu_add_device(struct device *dev)
 				dev_name(dev));
 
 		iommu_ignore_device(dev);
-		dev->dma_ops = &nommu_dma_ops;
+		dev->dma_ops = &dma_direct_ops;
 		goto out;
 	}
 	init_iommu_group(dev);
@@ -2667,7 +2668,7 @@ static void free_coherent(struct device *dev, size_t size,
  */
 static int amd_iommu_dma_supported(struct device *dev, u64 mask)
 {
-	if (!x86_dma_supported(dev, mask))
+	if (!dma_direct_supported(dev, mask))
 		return 0;
 	return check_device(dev);
 }
@@ -2781,7 +2782,7 @@ int __init amd_iommu_init_dma_ops(void)
 	 * continue to be SWIOTLB.
 	 */
 	if (!swiotlb)
-		dma_ops = &nommu_dma_ops;
+		dma_ops = &dma_direct_ops;
 
 	if (amd_iommu_unmap_flush)
 		pr_info("AMD-Vi: IO/TLB flush on unmap enabled\n");
drivers/iommu/intel-iommu.c +2 -1
index 4a2de34895ec..921caf4f0c3e 100644
@@ -45,6 +45,7 @@
 #include <linux/pci-ats.h>
 #include <linux/memblock.h>
 #include <linux/dma-contiguous.h>
+#include <linux/dma-direct.h>
 #include <linux/crash_dump.h>
 #include <asm/irq_remapping.h>
 #include <asm/cacheflush.h>
@@ -3872,7 +3873,7 @@ const struct dma_map_ops intel_dma_ops = {
 	.unmap_page = intel_unmap_page,
 	.mapping_error = intel_mapping_error,
 #ifdef CONFIG_X86
-	.dma_supported = x86_dma_supported,
+	.dma_supported = dma_direct_supported,
 #endif
 };
 
Signature · 1 line
2.14.2
#113 lore raw

PATCH 37/67 x86: use dma-direct

In reply to Christoph Hellwig

The generic dma-direct implementation is now functionally equivalent to the x86 nommu dma_map implementation, so switch over to using it.

Note that the various iommu drivers are switched from x86_dma_supported to dma_direct_supported to provide identical functionality, although the checks looks fairly questionable for at least some of them.

---
 arch/x86/Kconfig                   |  1 +
 arch/x86/include/asm/dma-mapping.h |  8 -----
 arch/x86/include/asm/iommu.h       |  3 --
 arch/x86/kernel/Makefile           |  2 +-
 arch/x86/kernel/amd_gart_64.c      |  7 ++--
 arch/x86/kernel/pci-calgary_64.c   |  3 +-
 arch/x86/kernel/pci-dma.c          | 66 +-------------------------------------
 arch/x86/kernel/pci-swiotlb.c      |  5 ++-
 arch/x86/pci/sta2x11-fixup.c       |  2 +-
 drivers/iommu/amd_iommu.c          |  7 ++--
 drivers/iommu/intel-iommu.c        |  3 +-
 11 files changed, 17 insertions(+), 90 deletions(-)
arch/x86/Kconfig +1 -0
index f6f4328103c0..55ad01515075 100644
@@ -83,6 +83,7 @@ config X86
 	select CLOCKSOURCE_VALIDATE_LAST_CYCLE
 	select CLOCKSOURCE_WATCHDOG
 	select DCACHE_WORD_ACCESS
+	select DMA_DIRECT_OPS
 	select EDAC_ATOMIC_SCRUB
 	select EDAC_SUPPORT
 	select GENERIC_CLOCKEVENTS
arch/x86/include/asm/dma-mapping.h +0 -8
index 545bf3721bc0..df9816b385eb 100644
@@ -36,14 +36,6 @@ int arch_dma_supported(struct device *dev, u64 mask);
 bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp);
 #define arch_dma_alloc_attrs arch_dma_alloc_attrs
 
-extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
-					dma_addr_t *dma_addr, gfp_t flag,
-					unsigned long attrs);
-
-extern void dma_generic_free_coherent(struct device *dev, size_t size,
-				      void *vaddr, dma_addr_t dma_addr,
-				      unsigned long attrs);
-
 static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp)
 {
 	if (dev->coherent_dma_mask <= DMA_BIT_MASK(24))
arch/x86/include/asm/iommu.h +0 -3
index 1e5d5d92eb40..baedab8ac538 100644
@@ -2,13 +2,10 @@
 #ifndef _ASM_X86_IOMMU_H
 #define _ASM_X86_IOMMU_H
 
-extern const struct dma_map_ops nommu_dma_ops;
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
 extern int iommu_pass_through;
 
-int x86_dma_supported(struct device *dev, u64 mask);
-
 /* 10 seconds */
 #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
 
arch/x86/kernel/Makefile +1 -1
index 81bb565f4497..beee4332e69b 100644
@@ -54,7 +54,7 @@ obj-$(CONFIG_X86_ESPFIX64)	+= espfix_64.o
 obj-$(CONFIG_SYSFS)	+= ksysfs.o
 obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o topology.o kdebugfs.o
-obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
+obj-y			+= alternative.o i8253.o hw_breakpoint.o
 obj-y			+= tsc.o tsc_msr.o io_delay.o rtc.o
 obj-y			+= pci-iommu_table.o
 obj-y			+= resource.o
arch/x86/kernel/amd_gart_64.c +3 -4
index ecd486cb06ab..52e3abcf3e70 100644
@@ -501,8 +501,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 		}
 		__free_pages(page, get_order(size));
 	} else
-		return dma_generic_alloc_coherent(dev, size, dma_addr, flag,
-						  attrs);
+		return dma_direct_alloc(dev, size, dma_addr, flag, attrs);
 
 	return NULL;
 }
@@ -513,7 +512,7 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr,
 		   dma_addr_t dma_addr, unsigned long attrs)
 {
 	gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, 0);
-	dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs);
+	dma_direct_free(dev, size, vaddr, dma_addr, attrs);
 }
 
 static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr)
@@ -705,7 +704,7 @@ static const struct dma_map_ops gart_dma_ops = {
 	.alloc				= gart_alloc_coherent,
 	.free				= gart_free_coherent,
 	.mapping_error			= gart_mapping_error,
-	.dma_supported			= x86_dma_supported,
+	.dma_supported			= dma_direct_supported,
 };
 
 static void gart_iommu_shutdown(void)
arch/x86/kernel/pci-calgary_64.c +2 -1
index 35c461f21815..5647853053bd 100644
@@ -33,6 +33,7 @@
 #include <linux/string.h>
 #include <linux/crash_dump.h>
 #include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/bitmap.h>
 #include <linux/pci_ids.h>
 #include <linux/pci.h>
@@ -493,7 +494,7 @@ static const struct dma_map_ops calgary_dma_ops = {
 	.map_page = calgary_map_page,
 	.unmap_page = calgary_unmap_page,
 	.mapping_error = calgary_mapping_error,
-	.dma_supported = x86_dma_supported,
+	.dma_supported = dma_direct_supported,
 };
 
 static inline void __iomem * busno_to_bbar(unsigned char num)
arch/x86/kernel/pci-dma.c +1 -65

84 lines not on this page · raw message

arch/x86/kernel/pci-swiotlb.c +2 -3
index 9d3e35c33d94..7a11a3e4f697 100644
@@ -30,8 +30,7 @@ void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 	 */
 	flags |= __GFP_NOWARN;
 
-	vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags,
-					   attrs);
+	vaddr = dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
 	if (vaddr)
 		return vaddr;
 
@@ -45,7 +44,7 @@ void x86_swiotlb_free_coherent(struct device *dev, size_t size,
 	if (is_swiotlb_buffer(dma_to_phys(dev, dma_addr)))
 		swiotlb_free_coherent(dev, size, vaddr, dma_addr);
 	else
-		dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs);
+		dma_direct_free(dev, size, vaddr, dma_addr, attrs);
 }
 
 static const struct dma_map_ops swiotlb_dma_ops = {
arch/x86/pci/sta2x11-fixup.c +1 -1
index 75577c1490c4..6c712fe11bdc 100644
@@ -193,7 +193,7 @@ static const struct dma_map_ops sta2x11_dma_ops = {
 	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
 	.sync_sg_for_device = swiotlb_sync_sg_for_device,
 	.mapping_error = swiotlb_dma_mapping_error,
-	.dma_supported = x86_dma_supported,
+	.dma_supported = dma_direct_supported,
 };
 
 /* At setup time, we use our own ops if the device is a ConneXt one */
drivers/iommu/amd_iommu.c +4 -3
index 7d5eb004091d..ea4734de5357 100644
@@ -28,6 +28,7 @@
 #include <linux/debugfs.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/dma-direct.h>
 #include <linux/iommu-helper.h>
 #include <linux/iommu.h>
 #include <linux/delay.h>
@@ -2182,7 +2183,7 @@ static int amd_iommu_add_device(struct device *dev)
 				dev_name(dev));
 
 		iommu_ignore_device(dev);
-		dev->dma_ops = &nommu_dma_ops;
+		dev->dma_ops = &dma_direct_ops;
 		goto out;
 	}
 	init_iommu_group(dev);
@@ -2667,7 +2668,7 @@ static void free_coherent(struct device *dev, size_t size,
  */
 static int amd_iommu_dma_supported(struct device *dev, u64 mask)
 {
-	if (!x86_dma_supported(dev, mask))
+	if (!dma_direct_supported(dev, mask))
 		return 0;
 	return check_device(dev);
 }
@@ -2781,7 +2782,7 @@ int __init amd_iommu_init_dma_ops(void)
 	 * continue to be SWIOTLB.
 	 */
 	if (!swiotlb)
-		dma_ops = &nommu_dma_ops;
+		dma_ops = &dma_direct_ops;
 
 	if (amd_iommu_unmap_flush)
 		pr_info("AMD-Vi: IO/TLB flush on unmap enabled\n");
drivers/iommu/intel-iommu.c +2 -1
index 4a2de34895ec..921caf4f0c3e 100644
@@ -45,6 +45,7 @@
 #include <linux/pci-ats.h>
 #include <linux/memblock.h>
 #include <linux/dma-contiguous.h>
+#include <linux/dma-direct.h>
 #include <linux/crash_dump.h>
 #include <asm/irq_remapping.h>
 #include <asm/cacheflush.h>
@@ -3872,7 +3873,7 @@ const struct dma_map_ops intel_dma_ops = {
 	.unmap_page = intel_unmap_page,
 	.mapping_error = intel_mapping_error,
 #ifdef CONFIG_X86
-	.dma_supported = x86_dma_supported,
+	.dma_supported = dma_direct_supported,
 #endif
 };
 
Signature · 1 line
2.14.2
#114 lore raw

PATCH 38/67 x86/amd_gart: clean up gart_alloc_coherent

In reply to Christoph Hellwig

Don't rely on the gfp mask from dma_alloc_coherent_gfp_flags to make the fallback decision, and streamline the code flow a bit.

---
 arch/x86/kernel/amd_gart_64.c | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)
arch/x86/kernel/amd_gart_64.c +18 -18
index 52e3abcf3e70..92054815023e 100644
@@ -484,26 +484,26 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 	unsigned long align_mask;
 	struct page *page;
 
-	if (force_iommu && !(flag & GFP_DMA)) {
-		flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
-		page = alloc_pages(flag | __GFP_ZERO, get_order(size));
-		if (!page)
-			return NULL;
-
-		align_mask = (1UL << get_order(size)) - 1;
-		paddr = dma_map_area(dev, page_to_phys(page), size,
-				     DMA_BIDIRECTIONAL, align_mask);
-
-		flush_gart();
-		if (paddr != bad_dma_addr) {
-			*dma_addr = paddr;
-			return page_address(page);
-		}
-		__free_pages(page, get_order(size));
-	} else
+	if (!force_iommu || dev->coherent_dma_mask <= DMA_BIT_MASK(24))
 		return dma_direct_alloc(dev, size, dma_addr, flag, attrs);
 
-	return NULL;
+	flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
+	page = alloc_pages(flag | __GFP_ZERO, get_order(size));
+	if (!page)
+		return NULL;
+
+	align_mask = (1UL << get_order(size)) - 1;
+	paddr = dma_map_area(dev, page_to_phys(page), size, DMA_BIDIRECTIONAL,
+			align_mask);
+
+	flush_gart();
+	if (unlikely(paddr == bad_dma_addr)) {
+		__free_pages(page, get_order(size));
+		return NULL;
+	}
+
+	*dma_addr = paddr;
+	return page_address(page);
 }
 
 /* free a coherent mapping */
Signature · 1 line
2.14.2
#115 lore raw

PATCH 38/67 x86/amd_gart: clean up gart_alloc_coherent

In reply to Christoph Hellwig

Don't rely on the gfp mask from dma_alloc_coherent_gfp_flags to make the fallback decision, and streamline the code flow a bit.

---
 arch/x86/kernel/amd_gart_64.c | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)
arch/x86/kernel/amd_gart_64.c +18 -18
index 52e3abcf3e70..92054815023e 100644
@@ -484,26 +484,26 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 	unsigned long align_mask;
 	struct page *page;
 
-	if (force_iommu && !(flag & GFP_DMA)) {
-		flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
-		page = alloc_pages(flag | __GFP_ZERO, get_order(size));
-		if (!page)
-			return NULL;
-
-		align_mask = (1UL << get_order(size)) - 1;
-		paddr = dma_map_area(dev, page_to_phys(page), size,
-				     DMA_BIDIRECTIONAL, align_mask);
-
-		flush_gart();
-		if (paddr != bad_dma_addr) {
-			*dma_addr = paddr;
-			return page_address(page);
-		}
-		__free_pages(page, get_order(size));
-	} else
+	if (!force_iommu || dev->coherent_dma_mask <= DMA_BIT_MASK(24))
 		return dma_direct_alloc(dev, size, dma_addr, flag, attrs);
 
-	return NULL;
+	flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
+	page = alloc_pages(flag | __GFP_ZERO, get_order(size));
+	if (!page)
+		return NULL;
+
+	align_mask = (1UL << get_order(size)) - 1;
+	paddr = dma_map_area(dev, page_to_phys(page), size, DMA_BIDIRECTIONAL,
+			align_mask);
+
+	flush_gart();
+	if (unlikely(paddr == bad_dma_addr)) {
+		__free_pages(page, get_order(size));
+		return NULL;
+	}
+
+	*dma_addr = paddr;
+	return page_address(page);
 }
 
 /* free a coherent mapping */
Signature · 1 line
2.14.2