consolidate direct dma mapping V4
Subsystems (31)
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 number of architectures to this generic direct map implemention.
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.
A git tree is also available:
git://git.infradead.org/users/hch/misc.git dma-direct.3
Gitweb:
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/dma-direct.3
Changes since V3
- new patch to fix an off-by-one in mips dma_capable
Changes since V2:
- fixed a few patch description typos
- fixed a few printk formats
- fixed an off by one in dma_coherent_ok
- add a few Reviewed-by/Acked-by tags.
- moved the swiotlb consolidation to a new series
- dropped a few patches for now to not overwhelem the x86 maintainers. They will be resubmitted in the next merge window
PATCH 1/34 alpha: mark jensen as broken
CONFIG_ALPHA_JENSEN has failed to compile since commit 6aca0503 ("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
@@ -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
PATCH 1/34 alpha: mark jensen as broken
In reply to Christoph HellwigCONFIG_ALPHA_JENSEN has failed to compile since commit 6aca0503 ("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
@@ -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
PATCH 2/34 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
@@ -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
PATCH 2/34 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
@@ -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
PATCH 3/34 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
@@ -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
PATCH 3/34 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
@@ -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
PATCH 4/34 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
@@ -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 1extern int dma_set_mask (struct device *dev,u64 dma_mask);
Signature · 1 line
2.14.2
PATCH 4/34 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
@@ -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 1extern int dma_set_mask (struct device *dev,u64 dma_mask);
Signature · 1 line
2.14.2
PATCH 5/34 arc: remove CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA
In reply to Christoph HellwigWe 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
@@ -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
@@ -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
@@ -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
PATCH 5/34 arc: remove CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA
In reply to Christoph HellwigWe 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
@@ -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
@@ -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
@@ -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
PATCH 6/34 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
@@ -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
PATCH 6/34 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
@@ -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
PATCH 7/34 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
@@ -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
PATCH 7/34 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
@@ -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
PATCH 8/34 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
@@ -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
PATCH 8/34 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
@@ -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
PATCH 9/34 dma-mapping: take dma_pfn_offset into account in dma_max_pfn
In reply to Christoph HellwigThis 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
@@ -692,7 +692,7 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)#ifndef dma_max_pfnstatic 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
PATCH 9/34 dma-mapping: take dma_pfn_offset into account in dma_max_pfn
In reply to Christoph HellwigThis 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
@@ -692,7 +692,7 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)#ifndef dma_max_pfnstatic 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
PATCH 10/34 arm64: don't override dma_max_pfn
In reply to Christoph HellwigThe 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
@@ -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
PATCH 10/34 arm64: don't override dma_max_pfn
In reply to Christoph HellwigThe 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
@@ -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
PATCH 11/34 mips: fix an off-by-one in dma_capable
In reply to Christoph HellwigThis makes it match the generic version.
--- arch/mips/include/asm/dma-mapping.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/include/asm/dma-mapping.h +1 -1
@@ -22,7 +22,7 @@ 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; +return addr + size -1 <= *dev->dma_mask; }static inline void dma_mark_clean (void *addr,size_t size) {}
Signature · 1 line
2.14.2
PATCH 11/34 mips: fix an off-by-one in dma_capable
In reply to Christoph HellwigThis makes it match the generic version.
--- arch/mips/include/asm/dma-mapping.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/include/asm/dma-mapping.h +1 -1
@@ -22,7 +22,7 @@ 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; +return addr + size -1 <= *dev->dma_mask; }static inline void dma_mark_clean (void *addr,size_t size) {}
Signature · 1 line
2.14.2
PATCH 12/34 dma-mapping: move swiotlb arch helpers to a new header
In reply to Christoph Hellwigphys_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.
In the MIPS case the existing dma-coherent.h is reused for now as untangling it will take a bit of work.
--- 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
@@ -4338,6 +4338,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1 @@ +#include <asm/dma-coherence.h>
arch/mips/include/asm/dma-mapping.h +0 -8
@@ -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 -1 <= *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
@@ -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 -1 <= *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
@@ -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
@@ -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 -1 <= *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
@@ -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
@@ -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
@@ -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
@@ -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 1int dma_set_mask (struct device *dev,u64 mask);
arch/unicore32/include/asm/dma-mapping.h +0 -18
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 12/34 dma-mapping: move swiotlb arch helpers to a new header
In reply to Christoph Hellwigphys_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.
In the MIPS case the existing dma-coherent.h is reused for now as untangling it will take a bit of work.
--- 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
@@ -4338,6 +4338,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1 @@ +#include <asm/dma-coherence.h>
arch/mips/include/asm/dma-mapping.h +0 -8
@@ -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 -1 <= *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
@@ -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 -1 <= *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
@@ -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
@@ -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 -1 <= *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
@@ -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
@@ -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
@@ -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
@@ -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 1int dma_set_mask (struct device *dev,u64 mask);
arch/unicore32/include/asm/dma-mapping.h +0 -18
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 13/34 dma-mapping: move dma_mark_clean to dma-direct.h
In reply to Christoph HellwigAnd 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 1int dma_set_mask (struct device *dev,u64 mask);
arch/unicore32/include/asm/dma-mapping.h +0 -2
@@ -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
@@ -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
@@ -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
PATCH 13/34 dma-mapping: move dma_mark_clean to dma-direct.h
In reply to Christoph HellwigAnd 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 1int dma_set_mask (struct device *dev,u64 mask);
arch/unicore32/include/asm/dma-mapping.h +0 -2
@@ -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
@@ -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
@@ -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
PATCH 14/34 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 -6
@@ -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; -}
PATCH 14/34 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
@@ -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
@@ -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
PATCH 15/34 powerpc: rename dma_direct_ to dma_nommu_
In reply to Christoph HellwigWe 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
@@ -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
@@ -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
@@ -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
171 lines not on this page · raw message
arch/powerpc/kernel/pci-common.c +1 -1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 15/34 powerpc: rename dma_direct_ to dma_nommu_
In reply to Christoph HellwigWe 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
@@ -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
@@ -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
@@ -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
171 lines not on this page · raw message
arch/powerpc/kernel/pci-common.c +1 -1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 16/34 microblaze: rename dma_direct to dma_nommu
In reply to Christoph HellwigThis frees the dma_direct_* namespace for a generic implementation.
--- arch/microblaze/include/asm/dma-mapping.h | 4 +-- arch/microblaze/kernel/dma.c | 48 +++++++++++++++---------------- 2 files changed, 26 insertions(+), 26 deletions(-)
arch/microblaze/include/asm/dma-mapping.h +2 -2
@@ -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 +24 -24
119 lines not on this page · raw message
Signature · 1 line
2.14.2
PATCH 16/34 microblaze: rename dma_direct to dma_nommu
In reply to Christoph HellwigThis frees the dma_direct_* namespace for a generic implementation.
--- arch/microblaze/include/asm/dma-mapping.h | 4 +-- arch/microblaze/kernel/dma.c | 48 +++++++++++++++---------------- 2 files changed, 26 insertions(+), 26 deletions(-)
arch/microblaze/include/asm/dma-mapping.h +2 -2
@@ -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 +24 -24
119 lines not on this page · raw message
Signature · 1 line
2.14.2
PATCH 17/34 microblaze: remove dma_nommu_dma_supported
In reply to Christoph HellwigAlways 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
@@ -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
@@ -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,
@@ -616,7 +610,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
PATCH 17/34 microblaze: remove dma_nommu_dma_supported
In reply to Christoph HellwigAlways 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
@@ -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
@@ -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,
@@ -616,7 +610,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
PATCH 18/34 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
@@ -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
PATCH 18/34 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
@@ -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
PATCH 19/34 s390: move s390_pci_dma_ops to asm/pci_dma.h
In reply to Christoph HellwigThis 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
@@ -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
@@ -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
PATCH 19/34 s390: move s390_pci_dma_ops to asm/pci_dma.h
In reply to Christoph HellwigThis 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
@@ -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
@@ -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
PATCH 20/34 dma-mapping: warn when there is no coherent_dma_mask
In reply to Christoph HellwigThese 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
@@ -513,6 +513,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
PATCH 20/34 dma-mapping: warn when there is no coherent_dma_mask
In reply to Christoph HellwigThese 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
@@ -513,6 +513,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
PATCH 21/34 dma-mapping: clear harmful GFP_* flags in common code
In reply to Christoph HellwigLift 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -518,6 +518,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
PATCH 21/34 dma-mapping: clear harmful GFP_* flags in common code
In reply to Christoph HellwigLift 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -518,6 +518,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
PATCH 22/34 dma-mapping: add an arch_dma_supported hook
In reply to Christoph HellwigTo 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
@@ -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
@@ -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
@@ -576,6 +576,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 )))
@@ -588,6 +596,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
Re: [PATCH 22/34] dma-mapping: add an arch_dma_supported hook
Quoted 16 lines · Christoph Hellwig
To implement the x86
forbid_dacandiommu_sac_forcewe want an arch hook so that it can apply the global options across alldma_map_opsimplementations.Signed-off-by Christoph Hellwig <[email protected]>--- 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(-)include/linux/dma-mapping.h +0
-0
include/linux/dma-mapping.h static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) · line 581
Quoted 6 lines
include/linux/dma-mapping.h +3
-0@@ -576,6 +576,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.
in new code.
Quoted 4 lines
include/linux/dma-mapping.h +4
-0+*/ +#ifndef arch_dma_supported +#define arch_dma_supported (dev, mask) (1) +#endif
Signature · 1 line
~Randy
Re: [PATCH 22/34] dma-mapping: add an arch_dma_supported hook
In reply to Christoph HellwigQuoted 16 lines · Christoph Hellwig
To implement the x86
forbid_dacandiommu_sac_forcewe want an arch hook so that it can apply the global options across alldma_map_opsimplementations.Signed-off-by Christoph Hellwig <[email protected]>--- 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(-)include/linux/dma-mapping.h +0
-0
include/linux/dma-mapping.h static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) · line 581
Quoted 6 lines
include/linux/dma-mapping.h +3
-0@@ -576,6 +576,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.
in new code.
Quoted 4 lines
include/linux/dma-mapping.h +4
-0+*/ +#ifndef arch_dma_supported +#define arch_dma_supported (dev, mask) (1) +#endif
Signature · 1 line
~Randy
PATCH 22/34 dma-mapping: add an arch_dma_supported hook
In reply to Christoph HellwigTo 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
@@ -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
@@ -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
@@ -576,6 +576,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 )))
@@ -588,6 +596,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
PATCH 23/34 dma-mapping: provide a generic asm/dma-mapping.h
In reply to Christoph HellwigFor 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
@@ -4338,6 +4338,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 23/34 dma-mapping: provide a generic asm/dma-mapping.h
In reply to Christoph HellwigFor 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
@@ -4338,6 +4338,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 24/34 dma-direct: rename dma_noop to dma_direct
In reply to Christoph HellwigThe 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} (52%)MAINTAINERS +1 -1
@@ -4334,7 +4334,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
@@ -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
@@ -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
@@ -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);
@@ -213,7 +213,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -136,7 +136,7 @@ struct dma_map_ops {int 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
@@ -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
@@ -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
@@ -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,11 +54,10 @@ static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nentreturn 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, }; - -EXPORT_SYMBOL (dma_noop_ops); +EXPORT_SYMBOL (dma_direct_ops);
Signature · 1 line
2.14.2
PATCH 24/34 dma-direct: rename dma_noop to dma_direct
In reply to Christoph HellwigThe 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} (52%)MAINTAINERS +1 -1
@@ -4334,7 +4334,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
@@ -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
@@ -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
@@ -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);
@@ -213,7 +213,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -136,7 +136,7 @@ struct dma_map_ops {int 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
@@ -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
@@ -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
@@ -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,11 +54,10 @@ static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nentreturn 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, }; - -EXPORT_SYMBOL (dma_noop_ops); +EXPORT_SYMBOL (dma_direct_ops);
Signature · 1 line
2.14.2
PATCH 25/34 dma-direct: use phys_to_dma
In reply to Christoph HellwigThis 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
@@ -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
PATCH 25/34 dma-direct: use phys_to_dma
In reply to Christoph HellwigThis 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
@@ -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
PATCH 26/34 dma-direct: add dma address sanity checks
In reply to Christoph HellwigRoughly based on the x86 pci-nommu implementation.
--- lib/dma-direct.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
lib/dma-direct.c +30 -1
@@ -9,6 +9,23 @@#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 %pad+%zu of device mask %llx\n" , + caller, &dma_addr, size, *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 +48,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,16 +65,24 @@ 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, };EXPORT_SYMBOL (dma_direct_ops);
Signature · 1 line
2.14.2
PATCH 26/34 dma-direct: add dma address sanity checks
In reply to Christoph HellwigRoughly based on the x86 pci-nommu implementation.
--- lib/dma-direct.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
lib/dma-direct.c +30 -1
@@ -9,6 +9,23 @@#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 %pad+%zu of device mask %llx\n" , + caller, &dma_addr, size, *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 +48,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,16 +65,24 @@ 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, };EXPORT_SYMBOL (dma_direct_ops);
Signature · 1 line
2.14.2
PATCH 27/34 dma-direct: add support for CMA allocation
In reply to Christoph HellwigTry 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
@@ -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
@@ -29,19 +30,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
PATCH 27/34 dma-direct: add support for CMA allocation
In reply to Christoph HellwigTry 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
@@ -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
@@ -29,19 +30,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
PATCH 28/34 dma-direct: use node local allocations for coherent memory
In reply to Christoph HellwigTo preserve the x86 behavior.
--- lib/dma-direct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/dma-direct.c +1 -1
@@ -38,7 +38,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
PATCH 28/34 dma-direct: use node local allocations for coherent memory
In reply to Christoph HellwigTo preserve the x86 behavior.
--- lib/dma-direct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/dma-direct.c +1 -1
@@ -38,7 +38,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
PATCH 29/34 dma-direct: add support for allocation from ZONE_DMA and ZONE_DMA32
In reply to Christoph HellwigThis allows to dip into zones for lower memory if they are available. If one of the zones is not available the corresponding GFP_* flag will evaluate to 0 so they won't change anything. We provide an arch tunable for those architectures that do not use GFP_DMA for the lowest 24-bits, given that there are a few.
Roughly based on the x86 code.
--- lib/dma-direct.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
lib/dma-direct.c +14 -0
@@ -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)
@@ -34,6 +42,12 @@ static void *dma_direct_alloc(struct device *dev, size_t size,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 (ARCH_ZONE_DMA_BITS )) + gfp |=GFP_DMA ; +if (dev->coherent_dma_mask <=DMA_BIT_MASK (32 ) && !(gfp &GFP_DMA )) + gfp |=GFP_DMA32 ; +/* 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);
Signature · 1 line
2.14.2
PATCH 29/34 dma-direct: add support for allocation from ZONE_DMA and ZONE_DMA32
In reply to Christoph HellwigThis allows to dip into zones for lower memory if they are available. If one of the zones is not available the corresponding GFP_* flag will evaluate to 0 so they won't change anything. We provide an arch tunable for those architectures that do not use GFP_DMA for the lowest 24-bits, given that there are a few.
Roughly based on the x86 code.
--- lib/dma-direct.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
lib/dma-direct.c +14 -0
@@ -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)
@@ -34,6 +42,12 @@ static void *dma_direct_alloc(struct device *dev, size_t size,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 (ARCH_ZONE_DMA_BITS )) + gfp |=GFP_DMA ; +if (dev->coherent_dma_mask <=DMA_BIT_MASK (32 ) && !(gfp &GFP_DMA )) + gfp |=GFP_DMA32 ; +/* 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);
Signature · 1 line
2.14.2
PATCH 30/34 dma-direct: retry allocations using GFP_DMA for small masks
In reply to Christoph HellwigIf an attempt to allocate memory succeeded, but isn't inside the supported DMA mask, retry the allocation with GFP_DMA set as a last resort.
Based on the x86 code, but an off by one error in what is now dma_coherent_ok has been fixed vs the x86 code.
--- lib/dma-direct.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
lib/dma-direct.c +24 -1
@@ -35,6 +35,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 -1 <= 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) {
@@ -48,11 +53,29 @@ static void *dma_direct_alloc(struct device *dev, size_t size,if (dev->coherent_dma_mask <=DMA_BIT_MASK (32 ) && !(gfp &GFP_DMA )) gfp |=GFP_DMA32 ; +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
PATCH 30/34 dma-direct: retry allocations using GFP_DMA for small masks
In reply to Christoph HellwigIf an attempt to allocate memory succeeded, but isn't inside the supported DMA mask, retry the allocation with GFP_DMA set as a last resort.
Based on the x86 code, but an off by one error in what is now dma_coherent_ok has been fixed vs the x86 code.
--- lib/dma-direct.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
lib/dma-direct.c +24 -1
@@ -35,6 +35,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 -1 <= 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) {
@@ -48,11 +53,29 @@ static void *dma_direct_alloc(struct device *dev, size_t size,if (dev->coherent_dma_mask <=DMA_BIT_MASK (32 ) && !(gfp &GFP_DMA )) gfp |=GFP_DMA32 ; +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
PATCH 31/34 dma-direct: make dma_direct_{alloc,free} available to other implementations
In reply to Christoph HellwigSo 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
@@ -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
@@ -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
@@ -40,8 +40,8 @@ static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)return phys_to_dma (dev, phys) + size -1 <= 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);
@@ -84,7 +84,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
PATCH 31/34 dma-direct: make dma_direct_{alloc,free} available to other implementations
In reply to Christoph HellwigSo 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
@@ -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
@@ -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
@@ -40,8 +40,8 @@ static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)return phys_to_dma (dev, phys) + size -1 <= 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);
@@ -84,7 +84,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
PATCH 32/34 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
@@ -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
@@ -122,6 +122,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 ;
@@ -132,6 +150,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, };EXPORT_SYMBOL (dma_direct_ops);
Signature · 1 line
2.14.2
PATCH 32/34 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
@@ -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
@@ -122,6 +122,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 ;
@@ -132,6 +150,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, };EXPORT_SYMBOL (dma_direct_ops);
Signature · 1 line
2.14.2
PATCH 33/34 cris: use dma-direct
In reply to Christoph Hellwigcris currently has an incomplete direct mapping dma_map_ops implementation if 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 | 77 --------------------------------- arch/cris/include/asm/Kbuild | 1 + arch/cris/include/asm/dma-mapping.h | 20 --------- 5 files changed, 6 insertions(+), 98 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
@@ -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
@@ -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 -77
77 lines not on this page · raw message
arch/cris/include/asm/Kbuild +1 -0
@@ -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
@@ -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
PATCH 33/34 cris: use dma-direct
In reply to Christoph Hellwigcris currently has an incomplete direct mapping dma_map_ops implementation if 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 | 77 --------------------------------- arch/cris/include/asm/Kbuild | 1 + arch/cris/include/asm/dma-mapping.h | 20 --------- 5 files changed, 6 insertions(+), 98 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
@@ -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
@@ -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 -77
77 lines not on this page · raw message
arch/cris/include/asm/Kbuild +1 -0
@@ -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
@@ -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
PATCH 34/34 h8300: use dma-direct
In reply to Christoph HellwigReplace 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 | 66 ------------------------------------ 5 files changed, 3 insertions(+), 79 deletions(-) delete mode 100644 arch/h8300/include/asm/dma-mapping.h delete mode 100644 arch/h8300/kernel/dma.c
arch/h8300/Kconfig +1 -0
@@ -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
@@ -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
@@ -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
@@ -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 -66
66 lines not on this page · raw message
Signature · 1 line
2.14.2
PATCH 34/34 h8300: use dma-direct
In reply to Christoph HellwigReplace 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 | 66 ------------------------------------ 5 files changed, 3 insertions(+), 79 deletions(-) delete mode 100644 arch/h8300/include/asm/dma-mapping.h delete mode 100644 arch/h8300/kernel/dma.c
arch/h8300/Kconfig +1 -0
@@ -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
@@ -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
@@ -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
@@ -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 -66
66 lines not on this page · raw message
Signature · 1 line
2.14.2
I've pulled this into the dma-mapping for-next branch so that we get a few days exposure before then end of the merge window. If there is anything important (e.g. the powerpc naming issue) please send incremental patches.
I've pulled this into the dma-mapping for-next branch so that we get a few days exposure before then end of the merge window. If there is anything important (e.g. the powerpc naming issue) please send incremental patches.