From 5299709d0a87342dadc1fc9850484fadeb488bf8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 20 Jan 2017 13:04:01 -0800 Subject: treewide: Constify most dma_map_ops structures Most dma_map_ops structures are never modified. Constify these structures such that these can be write-protected. This patch has been generated as follows: git grep -l 'struct dma_map_ops' | xargs -d\\n sed -i \ -e 's/struct dma_map_ops/const struct dma_map_ops/g' \ -e 's/const struct dma_map_ops {/struct dma_map_ops {/g' \ -e 's/^const struct dma_map_ops;$/struct dma_map_ops;/' \ -e 's/const const struct dma_map_ops /const struct dma_map_ops /g'; sed -i -e 's/const \(struct dma_map_ops intel_dma_ops\)/\1/' \ $(git grep -l 'struct dma_map_ops intel_dma_ops'); sed -i -e 's/const \(struct dma_map_ops dma_iommu_ops\)/\1/' \ $(git grep -l 'struct dma_map_ops' | grep ^arch/powerpc); sed -i -e '/^struct vmd_dev {$/,/^};$/ s/const \(struct dma_map_ops[[:blank:]]dma_ops;\)/\1/' \ -e '/^static void vmd_setup_dma_ops/,/^}$/ s/const \(struct dma_map_ops \*dest\)/\1/' \ -e 's/const \(struct dma_map_ops \*dest = \&vmd->dma_ops\)/\1/' \ drivers/pci/host/*.c sed -i -e '/^void __init pci_iommu_alloc(void)$/,/^}$/ s/dma_ops->/intel_dma_ops./' arch/ia64/kernel/pci-dma.c sed -i -e 's/static const struct dma_map_ops sn_dma_ops/static struct dma_map_ops sn_dma_ops/' arch/ia64/sn/pci/pci_dma.c sed -i -e 's/(const struct dma_map_ops \*)//' drivers/misc/mic/bus/vop_bus.c Signed-off-by: Bart Van Assche Reviewed-by: Christoph Hellwig Cc: Benjamin Herrenschmidt Cc: Boris Ostrovsky Cc: David Woodhouse Cc: Juergen Gross Cc: H. Peter Anvin Cc: Ingo Molnar Cc: linux-arch@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: Russell King Cc: x86@kernel.org Signed-off-by: Doug Ledford --- lib/dma-noop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/dma-noop.c b/lib/dma-noop.c index 3d766e78fbe2..65e49dd35b7b 100644 --- a/lib/dma-noop.c +++ b/lib/dma-noop.c @@ -64,7 +64,7 @@ static int dma_noop_supported(struct device *dev, u64 mask) return 1; } -struct dma_map_ops dma_noop_ops = { +const struct dma_map_ops dma_noop_ops = { .alloc = dma_noop_alloc, .free = dma_noop_free, .map_page = dma_noop_map_page, -- cgit v1.2.3 From 1eec9e2befd35270b19a91bb633db595dc55975e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 20 Jan 2017 13:04:05 -0800 Subject: lib/dma-noop: Clarify a comment The next patch in this series will introduce another set of DMA operations that map 1:1 with memory. Clarify that dma-noop maps to physical addresses. Signed-off-by: Bart Van Assche Cc: Christian Borntraeger Cc: Joerg Roedel Cc: Andy Lutomirski Cc: Michael S. Tsirkin Signed-off-by: Doug Ledford --- lib/dma-noop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/dma-noop.c b/lib/dma-noop.c index 65e49dd35b7b..de26c8b68f34 100644 --- a/lib/dma-noop.c +++ b/lib/dma-noop.c @@ -1,7 +1,7 @@ /* * lib/dma-noop.c * - * Simple DMA noop-ops that map 1:1 with memory + * DMA operations that map to physical addresses without flushing memory. */ #include #include -- cgit v1.2.3 From 7844572c633964c864d9f32dc3f2a8ffe5d70371 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 20 Jan 2017 13:04:06 -0800 Subject: lib/dma-noop: Only build dma_noop_ops for s390 and m32r Reduce the kernel size by only building dma_noop_ops for those architectures that actually use it. This was suggested by Christoph Hellwig. Signed-off-by: Bart Van Assche Cc: Christian Borntraeger Cc: Joerg Roedel Cc: Andy Lutomirski Cc: Michael S. Tsirkin Cc: Christoph Hellwig Signed-off-by: Doug Ledford --- arch/m32r/Kconfig | 1 + arch/s390/Kconfig | 1 + lib/Kconfig | 5 +++++ lib/Makefile | 2 +- 4 files changed, 8 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index d227a6988d6b..95474460b367 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -18,6 +18,7 @@ config M32R select MODULES_USE_ELF_RELA select HAVE_DEBUG_STACKOVERFLOW select CPU_NO_EFFICIENT_FFS + select DMA_NOOP_OPS config SBUS bool diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index c6722112527d..38ad42358c41 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -137,6 +137,7 @@ config S390 select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_API_DEBUG select HAVE_DMA_CONTIGUOUS + select DMA_NOOP_OPS select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_EFFICIENT_UNALIGNED_ACCESS diff --git a/lib/Kconfig b/lib/Kconfig index 260a80e313b9..b6baf0609e8b 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -395,6 +395,11 @@ config HAS_DMA depends on !NO_DMA default y +config DMA_NOOP_OPS + bool + depends on HAS_DMA && (!64BIT || ARCH_DMA_ADDR_T_64BIT) + default n + config CHECK_SIGNATURE bool diff --git a/lib/Makefile b/lib/Makefile index bc4073a8cd08..ada06d5652e8 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -26,7 +26,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o -lib-$(CONFIG_HAS_DMA) += dma-noop.o +lib-$(CONFIG_DMA_NOOP_OPS) += dma-noop.o lib-y += kobject.o klist.o obj-y += lockref.o -- cgit v1.2.3 From 551199aca1c3102ebed390566d681cc1290284ca Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 20 Jan 2017 13:04:07 -0800 Subject: lib/dma-virt: Add dma_virt_ops Several RDMA drivers (hfi1, qib and rxe) expect that ib_sge.addr is a virtual address. Provide DMA mapping operations that are suitable for these drivers. Signed-off-by: Bart Van Assche Cc: Christian Borntraeger Cc: Joerg Roedel Cc: Andy Lutomirski Cc: Michael S. Tsirkin Signed-off-by: Doug Ledford --- include/linux/dma-mapping.h | 1 + lib/Kconfig | 5 ++++ lib/Makefile | 1 + lib/dma-virt.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 lib/dma-virt.c (limited to 'lib') diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index ab8710888ddf..426c43d4fdbf 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -128,6 +128,7 @@ struct dma_map_ops { }; extern const struct dma_map_ops dma_noop_ops; +extern const struct dma_map_ops dma_virt_ops; #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) diff --git a/lib/Kconfig b/lib/Kconfig index b6baf0609e8b..97af23b26f33 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -400,6 +400,11 @@ config DMA_NOOP_OPS depends on HAS_DMA && (!64BIT || ARCH_DMA_ADDR_T_64BIT) default n +config DMA_VIRT_OPS + bool + depends on HAS_DMA && (!64BIT || ARCH_DMA_ADDR_T_64BIT) + default n + config CHECK_SIGNATURE bool diff --git a/lib/Makefile b/lib/Makefile index ada06d5652e8..b97e9a814854 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -27,6 +27,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_VIRT_OPS) += dma-virt.o lib-y += kobject.o klist.o obj-y += lockref.o diff --git a/lib/dma-virt.c b/lib/dma-virt.c new file mode 100644 index 000000000000..dcd4df1f7174 --- /dev/null +++ b/lib/dma-virt.c @@ -0,0 +1,72 @@ +/* + * lib/dma-virt.c + * + * DMA operations that map to virtual addresses without flushing memory. + */ +#include +#include +#include +#include + +static void *dma_virt_alloc(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + unsigned long attrs) +{ + void *ret; + + ret = (void *)__get_free_pages(gfp, get_order(size)); + if (ret) + *dma_handle = (uintptr_t)ret; + return ret; +} + +static void dma_virt_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_virt_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + unsigned long attrs) +{ + return (uintptr_t)(page_address(page) + offset); +} + +static int dma_virt_map_sg(struct device *dev, struct scatterlist *sgl, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + int i; + struct scatterlist *sg; + + for_each_sg(sgl, sg, nents, i) { + BUG_ON(!sg_page(sg)); + sg_dma_address(sg) = (uintptr_t)sg_virt(sg); + sg_dma_len(sg) = sg->length; + } + + return nents; +} + +static int dma_virt_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return false; +} + +static int dma_virt_supported(struct device *dev, u64 mask) +{ + return true; +} + +const struct dma_map_ops dma_virt_ops = { + .alloc = dma_virt_alloc, + .free = dma_virt_free, + .map_page = dma_virt_map_page, + .map_sg = dma_virt_map_sg, + .mapping_error = dma_virt_mapping_error, + .dma_supported = dma_virt_supported, +}; +EXPORT_SYMBOL(dma_virt_ops); -- cgit v1.2.3