Skip to content

Commit

Permalink
Merge tag 'dma-mapping-4.16' of git://git.infradead.org/users/hch/dma…
Browse files Browse the repository at this point in the history
…-mapping

Pull dma mapping updates from Christoph Hellwig:
 "Except for a runtime warning fix from Christian this is all about
  consolidation of the generic no-IOMMU code, a well as the glue code
  for swiotlb.

  All the code is based on the x86 implementation with hooks to allow
  all architectures that aren't cache coherent to use it.

  The x86 conversion itself has been deferred because the x86
  maintainers were a little busy in the last months"

* tag 'dma-mapping-4.16' of git://git.infradead.org/users/hch/dma-mapping: (57 commits)
  MAINTAINERS: add the iommu list for swiotlb and xen-swiotlb
  arm64: use swiotlb_alloc and swiotlb_free
  arm64: replace ZONE_DMA with ZONE_DMA32
  mips: use swiotlb_{alloc,free}
  mips/netlogic: remove swiotlb support
  tile: use generic swiotlb_ops
  tile: replace ZONE_DMA with ZONE_DMA32
  unicore32: use generic swiotlb_ops
  ia64: remove an ifdef around the content of pci-dma.c
  ia64: clean up swiotlb support
  ia64: use generic swiotlb_ops
  ia64: replace ZONE_DMA with ZONE_DMA32
  swiotlb: remove various exports
  swiotlb: refactor coherent buffer allocation
  swiotlb: refactor coherent buffer freeing
  swiotlb: wire up ->dma_supported in swiotlb_dma_ops
  swiotlb: add common swiotlb_map_ops
  swiotlb: rename swiotlb_free to swiotlb_exit
  x86: rename swiotlb_dma_ops
  powerpc: rename swiotlb_dma_ops
  ...
  • Loading branch information
torvalds committed Jan 31, 2018
2 parents 28bc6fb + 04f5653 commit 2382dc9
Show file tree
Hide file tree
Showing 119 changed files with 728 additions and 1,266 deletions.
7 changes: 5 additions & 2 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4343,10 +4343,12 @@ 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
F: include/asm-generic/dma-mapping.h
F: include/linux/dma-direct.h
F: include/linux/dma-mapping.h

DME1737 HARDWARE MONITOR DRIVER
Expand Down Expand Up @@ -13071,7 +13073,7 @@ F: arch/x86/boot/video*

SWIOTLB SUBSYSTEM
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
L: linux-kernel@vger.kernel.org
L: iommu@lists.linux-foundation.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb.git
S: Supported
F: lib/swiotlb.c
Expand Down Expand Up @@ -15026,6 +15028,7 @@ F: include/xen/interface/io/vscsiif.h
XEN SWIOTLB SUBSYSTEM
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
L: xen-devel@lists.xenproject.org (moderated for non-subscribers)
L: iommu@lists.linux-foundation.org
S: Supported
F: arch/x86/xen/*swiotlb*
F: drivers/xen/*swiotlb*
Expand Down
4 changes: 4 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions arch/alpha/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 0 additions & 7 deletions arch/arc/include/asm/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 7 additions & 7 deletions arch/arc/mm/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -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;
}

/*
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -24,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
Expand Down
36 changes: 36 additions & 0 deletions arch/arm/include/asm/dma-direct.h
Original file line number Diff line number Diff line change
@@ -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 */
35 changes: 1 addition & 34 deletions arch/arm/include/asm/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -109,39 +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) { }

/**
* arm_dma_alloc - allocate consistent memory for DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
Expand Down
13 changes: 5 additions & 8 deletions arch/arm/mm/dma-mapping-nommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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
Expand All @@ -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_noop_ops;
void *ret;

/*
Expand All @@ -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);

Expand All @@ -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_noop_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);
Expand Down Expand Up @@ -213,7 +210,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,
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ config ARM64
select COMMON_CLK
select CPU_PM if (SUSPEND || CPU_IDLE)
select DCACHE_WORD_ACCESS
select DMA_DIRECT_OPS
select EDAC_SUPPORT
select FRAME_POINTER
select GENERIC_ALLOCATOR
Expand Down Expand Up @@ -227,7 +228,7 @@ config GENERIC_CSUM
config GENERIC_CALIBRATE_DELAY
def_bool y

config ZONE_DMA
config ZONE_DMA32
def_bool y

config HAVE_GENERIC_GUP
Expand Down
35 changes: 0 additions & 35 deletions arch/arm64/include/asm/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,40 +50,5 @@ 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)
{
}

/* 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 */
Loading

0 comments on commit 2382dc9

Please sign in to comment.