iommu.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* dma-mapping cleanups
@ 2020-09-08 16:47 Christoph Hellwig
  2020-09-08 16:47 ` [PATCH 01/12] MIPS: make dma_sync_*_for_cpu a little less overzealous Christoph Hellwig
                   ` (11 more replies)
  0 siblings, 12 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

Hi all,

this series contains just the cleanup parts from the previous
"a saner API for allocating DMA addressable pages" series.  The
intent is to get this in to reduce the amount of patchbombing
for iterations of the real API work.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 01/12] MIPS: make dma_sync_*_for_cpu a little less overzealous
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-08 16:47 ` [PATCH 02/12] MIPS/jazzdma: remove the unused vdma_remap function Christoph Hellwig
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

When transferring DMA ownership back to the CPU there should never
be any writeback from the cache, as the buffer was owned by the
device until now.  Instead it should just be invalidated for the
mapping directions where the device could have written data.
Note that the changes rely on the fact that kmap_atomic is stubbed
out for the !HIGHMEM case to simplify the code a bit.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/mm/dma-noncoherent.c | 44 +++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 563c2c0d0c8193..97a14adbafc99c 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -55,22 +55,34 @@ void *arch_dma_set_uncached(void *addr, size_t size)
 	return (void *)(__pa(addr) + UNCAC_BASE);
 }
 
-static inline void dma_sync_virt(void *addr, size_t size,
+static inline void dma_sync_virt_for_device(void *addr, size_t size,
 		enum dma_data_direction dir)
 {
 	switch (dir) {
 	case DMA_TO_DEVICE:
 		dma_cache_wback((unsigned long)addr, size);
 		break;
-
 	case DMA_FROM_DEVICE:
 		dma_cache_inv((unsigned long)addr, size);
 		break;
-
 	case DMA_BIDIRECTIONAL:
 		dma_cache_wback_inv((unsigned long)addr, size);
 		break;
+	default:
+		BUG();
+	}
+}
 
+static inline void dma_sync_virt_for_cpu(void *addr, size_t size,
+		enum dma_data_direction dir)
+{
+	switch (dir) {
+	case DMA_TO_DEVICE:
+		break;
+	case DMA_FROM_DEVICE:
+	case DMA_BIDIRECTIONAL:
+		dma_cache_inv((unsigned long)addr, size);
+		break;
 	default:
 		BUG();
 	}
@@ -82,7 +94,7 @@ static inline void dma_sync_virt(void *addr, size_t size,
  * configured then the bulk of this loop gets optimized out.
  */
 static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
-		enum dma_data_direction dir)
+		enum dma_data_direction dir, bool for_device)
 {
 	struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
 	unsigned long offset = paddr & ~PAGE_MASK;
@@ -90,18 +102,20 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
 
 	do {
 		size_t len = left;
+		void *addr;
 
 		if (PageHighMem(page)) {
-			void *addr;
-
 			if (offset + len > PAGE_SIZE)
 				len = PAGE_SIZE - offset;
+		}
+
+		addr = kmap_atomic(page);
+		if (for_device)
+			dma_sync_virt_for_device(addr + offset, len, dir);
+		else
+			dma_sync_virt_for_cpu(addr + offset, len, dir);
+		kunmap_atomic(addr);
 
-			addr = kmap_atomic(page);
-			dma_sync_virt(addr + offset, len, dir);
-			kunmap_atomic(addr);
-		} else
-			dma_sync_virt(page_address(page) + offset, size, dir);
 		offset = 0;
 		page++;
 		left -= len;
@@ -111,7 +125,7 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
 void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
-	dma_sync_phys(paddr, size, dir);
+	dma_sync_phys(paddr, size, dir, true);
 }
 
 #ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
@@ -119,16 +133,14 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
 	if (cpu_needs_post_dma_flush())
-		dma_sync_phys(paddr, size, dir);
+		dma_sync_phys(paddr, size, dir, false);
 }
 #endif
 
 void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 		enum dma_data_direction direction)
 {
-	BUG_ON(direction == DMA_NONE);
-
-	dma_sync_virt(vaddr, size, direction);
+	dma_sync_virt_for_device(vaddr, size, direction);
 }
 
 #ifdef CONFIG_DMA_PERDEV_COHERENT
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 02/12] MIPS/jazzdma: remove the unused vdma_remap function
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
  2020-09-08 16:47 ` [PATCH 01/12] MIPS: make dma_sync_*_for_cpu a little less overzealous Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-08 16:47 ` [PATCH 03/12] MIPS/jazzdma: decouple from dma-direct Christoph Hellwig
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/include/asm/jazzdma.h |  2 -
 arch/mips/jazz/jazzdma.c        | 70 ---------------------------------
 2 files changed, 72 deletions(-)

diff --git a/arch/mips/include/asm/jazzdma.h b/arch/mips/include/asm/jazzdma.h
index d13f940022d5f9..c831da7fa89803 100644
--- a/arch/mips/include/asm/jazzdma.h
+++ b/arch/mips/include/asm/jazzdma.h
@@ -10,8 +10,6 @@
  */
 extern unsigned long vdma_alloc(unsigned long paddr, unsigned long size);
 extern int vdma_free(unsigned long laddr);
-extern int vdma_remap(unsigned long laddr, unsigned long paddr,
-		      unsigned long size);
 extern unsigned long vdma_phys2log(unsigned long paddr);
 extern unsigned long vdma_log2phys(unsigned long laddr);
 extern void vdma_stats(void);		/* for debugging only */
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
index 014773f0bfcd74..fe40dbed04c1d6 100644
--- a/arch/mips/jazz/jazzdma.c
+++ b/arch/mips/jazz/jazzdma.c
@@ -209,76 +209,6 @@ int vdma_free(unsigned long laddr)
 
 EXPORT_SYMBOL(vdma_free);
 
-/*
- * Map certain page(s) to another physical address.
- * Caller must have allocated the page(s) before.
- */
-int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size)
-{
-	int first, pages;
-
-	if (laddr > 0xffffff) {
-		if (vdma_debug)
-			printk
-			    ("vdma_map: Invalid logical address: %08lx\n",
-			     laddr);
-		return -EINVAL; /* invalid logical address */
-	}
-	if (paddr > 0x1fffffff) {
-		if (vdma_debug)
-			printk
-			    ("vdma_map: Invalid physical address: %08lx\n",
-			     paddr);
-		return -EINVAL; /* invalid physical address */
-	}
-
-	pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
-	first = laddr >> 12;
-	if (vdma_debug)
-		printk("vdma_remap: first=%x, pages=%x\n", first, pages);
-	if (first + pages > VDMA_PGTBL_ENTRIES) {
-		if (vdma_debug)
-			printk("vdma_alloc: Invalid size: %08lx\n", size);
-		return -EINVAL;
-	}
-
-	paddr &= ~(VDMA_PAGESIZE - 1);
-	while (pages > 0 && first < VDMA_PGTBL_ENTRIES) {
-		if (pgtbl[first].owner != laddr) {
-			if (vdma_debug)
-				printk("Trying to remap other's pages.\n");
-			return -EPERM;	/* not owner */
-		}
-		pgtbl[first].frame = paddr;
-		paddr += VDMA_PAGESIZE;
-		first++;
-		pages--;
-	}
-
-	/*
-	 * Update translation table
-	 */
-	r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
-
-	if (vdma_debug > 2) {
-		int i;
-		pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
-		first = laddr >> 12;
-		printk("LADDR: ");
-		for (i = first; i < first + pages; i++)
-			printk("%08x ", i << 12);
-		printk("\nPADDR: ");
-		for (i = first; i < first + pages; i++)
-			printk("%08x ", pgtbl[i].frame);
-		printk("\nOWNER: ");
-		for (i = first; i < first + pages; i++)
-			printk("%08x ", pgtbl[i].owner);
-		printk("\n");
-	}
-
-	return 0;
-}
-
 /*
  * Translate a physical address to a logical address.
  * This will return the logical address of the first
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 03/12] MIPS/jazzdma: decouple from dma-direct
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
  2020-09-08 16:47 ` [PATCH 01/12] MIPS: make dma_sync_*_for_cpu a little less overzealous Christoph Hellwig
  2020-09-08 16:47 ` [PATCH 02/12] MIPS/jazzdma: remove the unused vdma_remap function Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-08 16:47 ` [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies Christoph Hellwig
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

The jazzdma ops implement support for a very basic IOMMU.  Thus we really
should not use the dma-direct code that takes physical address limits
into account.  This survived through the great MIPS DMA ops cleanup mostly
because I was lazy, but now it is time to fully split the implementations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/jazz/jazzdma.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
index fe40dbed04c1d6..d0b5a2ba2b1a8a 100644
--- a/arch/mips/jazz/jazzdma.c
+++ b/arch/mips/jazz/jazzdma.c
@@ -16,7 +16,6 @@
 #include <linux/memblock.h>
 #include <linux/spinlock.h>
 #include <linux/gfp.h>
-#include <linux/dma-direct.h>
 #include <linux/dma-noncoherent.h>
 #include <asm/mipsregs.h>
 #include <asm/jazz.h>
@@ -492,26 +491,38 @@ int vdma_get_enable(int channel)
 static void *jazz_dma_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
+	struct page *page;
 	void *ret;
 
-	ret = dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
-	if (!ret)
-		return NULL;
+	if (attrs & DMA_ATTR_NO_WARN)
+		gfp |= __GFP_NOWARN;
 
-	*dma_handle = vdma_alloc(virt_to_phys(ret), size);
-	if (*dma_handle == DMA_MAPPING_ERROR) {
-		dma_direct_free_pages(dev, size, ret, *dma_handle, attrs);
+	size = PAGE_ALIGN(size);
+	page = alloc_pages(gfp, get_order(size));
+	if (!page)
 		return NULL;
-	}
+	ret = page_address(page);
+	*dma_handle = vdma_alloc(virt_to_phys(ret), size);
+	if (*dma_handle == DMA_MAPPING_ERROR)
+		goto out_free_pages;
+
+	if (attrs & DMA_ATTR_NON_CONSISTENT)
+		return ret;
+	arch_dma_prep_coherent(page, size);
+	return (void *)(UNCAC_BASE + __pa(ret));
 
-	return ret;
+out_free_pages:
+	__free_pages(page, get_order(size));
+	return NULL;
 }
 
 static void jazz_dma_free(struct device *dev, size_t size, void *vaddr,
 		dma_addr_t dma_handle, unsigned long attrs)
 {
 	vdma_free(dma_handle);
-	dma_direct_free_pages(dev, size, vaddr, dma_handle, attrs);
+	if (!(attrs & DMA_ATTR_NON_CONSISTENT))
+		vaddr = __va(vaddr - UNCAC_BASE);
+	__free_pages(virt_to_page(vaddr), get_order(size));
 }
 
 static dma_addr_t jazz_dma_map_page(struct device *dev, struct page *page,
@@ -608,7 +619,6 @@ const struct dma_map_ops jazz_dma_ops = {
 	.sync_single_for_device	= jazz_dma_sync_single_for_device,
 	.sync_sg_for_cpu	= jazz_dma_sync_sg_for_cpu,
 	.sync_sg_for_device	= jazz_dma_sync_sg_for_device,
-	.dma_supported		= dma_direct_supported,
 	.cache_sync		= arch_dma_cache_sync,
 	.mmap			= dma_common_mmap,
 	.get_sgtable		= dma_common_get_sgtable,
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
                   ` (2 preceding siblings ...)
  2020-09-08 16:47 ` [PATCH 03/12] MIPS/jazzdma: decouple from dma-direct Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-08 18:04   ` Sergei Shtylyov
  2020-09-10 12:55   ` Robin Murphy
  2020-09-08 16:47 ` [PATCH 05/12] dma-mapping: add (back) arch_dma_mark_clean for ia64 Christoph Hellwig
                   ` (7 subsequent siblings)
  11 siblings, 2 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

Driver that select DMA_OPS need to depend on HAS_DMA support to
work.  The vop driver was missing that dependency, so add it, and also
add a nother depends in DMA_OPS itself.  That won't fix the issue due
to how the Kconfig dependencies work, but at least produce a warning
about unmet dependencies.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/misc/mic/Kconfig | 1 +
 kernel/dma/Kconfig       | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
index b9bb086785db48..8a7c2c5711d5f4 100644
--- a/drivers/misc/mic/Kconfig
+++ b/drivers/misc/mic/Kconfig
@@ -35,6 +35,7 @@ config SCIF_BUS
 
 config VOP_BUS
 	tristate "VOP Bus Driver"
+	depends on HAS_DMA
 	select DMA_OPS
 	help
 	  This option is selected by any driver which registers a
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index 0ddfb5510fe45f..e7b801649f6574 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -9,6 +9,7 @@ config HAS_DMA
 	default y
 
 config DMA_OPS
+	depends on HAS_DMA
 	bool
 
 #
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 05/12] dma-mapping: add (back) arch_dma_mark_clean for ia64
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
                   ` (3 preceding siblings ...)
  2020-09-08 16:47 ` [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-08 16:47 ` [PATCH 06/12] dma-direct: remove dma_direct_{alloc,free}_pages Christoph Hellwig
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

Add back a hook to optimize dcache flushing after reading executable
code using DMA.  This gets ia64 out of the business of pretending to
be dma incoherent just for this optimization.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/ia64/Kconfig               |  3 +--
 arch/ia64/kernel/dma-mapping.c  | 14 +-------------
 arch/ia64/mm/init.c             |  3 +--
 include/linux/dma-direct.h      |  3 +++
 include/linux/dma-noncoherent.h |  8 ++++++++
 kernel/dma/Kconfig              |  6 ++++++
 kernel/dma/direct.c             |  3 +++
 7 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 5b4ec80bf5863a..513ba0c5d33610 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -8,6 +8,7 @@ menu "Processor type and features"
 
 config IA64
 	bool
+	select ARCH_HAS_DMA_MARK_CLEAN
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
 	select ACPI
@@ -32,8 +33,6 @@ config IA64
 	select TTY
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_VIRT_CPU_ACCOUNTING
-	select DMA_NONCOHERENT_MMAP
-	select ARCH_HAS_SYNC_DMA_FOR_CPU
 	select VIRT_TO_BUS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_PENDING_IRQ if SMP
diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c
index 09ef9ce9988d1f..f640ed6fe1d576 100644
--- a/arch/ia64/kernel/dma-mapping.c
+++ b/arch/ia64/kernel/dma-mapping.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/dma-direct.h>
+#include <linux/dma-mapping.h>
 #include <linux/export.h>
 
 /* Set this to 1 if there is a HW IOMMU in the system */
@@ -7,15 +7,3 @@ int iommu_detected __read_mostly;
 
 const struct dma_map_ops *dma_ops;
 EXPORT_SYMBOL(dma_ops);
-
-void *arch_dma_alloc(struct device *dev, size_t size,
-		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
-{
-	return dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
-}
-
-void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
-		dma_addr_t dma_addr, unsigned long attrs)
-{
-	dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs);
-}
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 0b3fb4c7af2920..02e5aa08294ee0 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -73,8 +73,7 @@ __ia64_sync_icache_dcache (pte_t pte)
  * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to
  * flush them when they get mapped into an executable vm-area.
  */
-void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
-		enum dma_data_direction dir)
+void arch_dma_mark_clean(phys_addr_t paddr, size_t size)
 {
 	unsigned long pfn = PHYS_PFN(paddr);
 
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index 6e87225600ae35..95e3e28bd93f47 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -150,6 +150,9 @@ static inline void dma_direct_sync_single_for_cpu(struct device *dev,
 
 	if (unlikely(is_swiotlb_buffer(paddr)))
 		swiotlb_tbl_sync_single(dev, paddr, size, dir, SYNC_FOR_CPU);
+
+	if (dir == DMA_FROM_DEVICE)
+		arch_dma_mark_clean(paddr, size);
 }
 
 static inline dma_addr_t dma_direct_map_page(struct device *dev,
diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
index ca09a4e07d2d3d..b9bc6c557ea46f 100644
--- a/include/linux/dma-noncoherent.h
+++ b/include/linux/dma-noncoherent.h
@@ -108,6 +108,14 @@ static inline void arch_dma_prep_coherent(struct page *page, size_t size)
 }
 #endif /* CONFIG_ARCH_HAS_DMA_PREP_COHERENT */
 
+#ifdef CONFIG_ARCH_HAS_DMA_MARK_CLEAN
+void arch_dma_mark_clean(phys_addr_t paddr, size_t size);
+#else
+static inline void arch_dma_mark_clean(phys_addr_t paddr, size_t size)
+{
+}
+#endif /* ARCH_HAS_DMA_MARK_CLEAN */
+
 void *arch_dma_set_uncached(void *addr, size_t size);
 void arch_dma_clear_uncached(void *addr, size_t size);
 
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index e7b801649f6574..281785feb874db 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -44,6 +44,12 @@ config ARCH_HAS_DMA_SET_MASK
 config ARCH_HAS_DMA_WRITE_COMBINE
 	bool
 
+#
+# Select if the architectures provides the arch_dma_mark_clean hook
+#
+config ARCH_HAS_DMA_MARK_CLEAN
+	bool
+
 config DMA_DECLARE_COHERENT
 	bool
 
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index db6ef07aec3b37..949c1cbf08b2d5 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -345,6 +345,9 @@ void dma_direct_sync_sg_for_cpu(struct device *dev,
 		if (unlikely(is_swiotlb_buffer(paddr)))
 			swiotlb_tbl_sync_single(dev, paddr, sg->length, dir,
 					SYNC_FOR_CPU);
+
+		if (dir == DMA_FROM_DEVICE)
+			arch_dma_mark_clean(paddr, sg->length);
 	}
 
 	if (!dev_is_dma_coherent(dev))
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 06/12] dma-direct: remove dma_direct_{alloc,free}_pages
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
                   ` (4 preceding siblings ...)
  2020-09-08 16:47 ` [PATCH 05/12] dma-mapping: add (back) arch_dma_mark_clean for ia64 Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-10 12:57   ` Robin Murphy
  2020-09-08 16:47 ` [PATCH 07/12] dma-direct: lift gfp_t manipulation out of__dma_direct_alloc_pages Christoph Hellwig
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

Just merge these helpers into the main dma_direct_{alloc,free} routines,
as the additional checks are always false for the two callers.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/x86/kernel/amd_gart_64.c |  6 +++---
 include/linux/dma-direct.h    |  4 ----
 kernel/dma/direct.c           | 39 ++++++++++++++---------------------
 kernel/dma/pool.c             |  2 +-
 4 files changed, 19 insertions(+), 32 deletions(-)

diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index bccc5357bffd6c..153374b996a279 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -467,7 +467,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 {
 	void *vaddr;
 
-	vaddr = dma_direct_alloc_pages(dev, size, dma_addr, flag, attrs);
+	vaddr = dma_direct_alloc(dev, size, dma_addr, flag, attrs);
 	if (!vaddr ||
 	    !force_iommu || dev->coherent_dma_mask <= DMA_BIT_MASK(24))
 		return vaddr;
@@ -479,7 +479,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 		goto out_free;
 	return vaddr;
 out_free:
-	dma_direct_free_pages(dev, size, vaddr, *dma_addr, attrs);
+	dma_direct_free(dev, size, vaddr, *dma_addr, attrs);
 	return NULL;
 }
 
@@ -489,7 +489,7 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr,
 		   dma_addr_t dma_addr, unsigned long attrs)
 {
 	gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, 0);
-	dma_direct_free_pages(dev, size, vaddr, dma_addr, attrs);
+	dma_direct_free(dev, size, vaddr, dma_addr, attrs);
 }
 
 static int no_agp;
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index 95e3e28bd93f47..20eceb2e4f91f8 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -77,10 +77,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);
-void *dma_direct_alloc_pages(struct device *dev, size_t size,
-		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs);
-void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
-		dma_addr_t dma_addr, unsigned long attrs);
 int dma_direct_get_sgtable(struct device *dev, struct sg_table *sgt,
 		void *cpu_addr, dma_addr_t dma_addr, size_t size,
 		unsigned long attrs);
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 949c1cbf08b2d5..1d564bea58571b 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -151,13 +151,18 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
 	return page;
 }
 
-void *dma_direct_alloc_pages(struct device *dev, size_t size,
+void *dma_direct_alloc(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
 	struct page *page;
 	void *ret;
 	int err;
 
+	if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
+	    !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
+	    dma_alloc_need_uncached(dev, attrs))
+		return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
+
 	size = PAGE_ALIGN(size);
 
 	if (dma_should_alloc_from_pool(dev, gfp, attrs)) {
@@ -256,11 +261,18 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size,
 	return NULL;
 }
 
-void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
-		dma_addr_t dma_addr, unsigned long attrs)
+void dma_direct_free(struct device *dev, size_t size,
+		void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs)
 {
 	unsigned int page_order = get_order(size);
 
+	if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
+	    !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
+	    dma_alloc_need_uncached(dev, attrs)) {
+		arch_dma_free(dev, size, cpu_addr, dma_addr, attrs);
+		return;
+	}
+
 	/* If cpu_addr is not from an atomic pool, dma_free_from_pool() fails */
 	if (dma_should_free_from_pool(dev, attrs) &&
 	    dma_free_from_pool(dev, cpu_addr, PAGE_ALIGN(size)))
@@ -284,27 +296,6 @@ void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
 	dma_free_contiguous(dev, dma_direct_to_page(dev, dma_addr), size);
 }
 
-void *dma_direct_alloc(struct device *dev, size_t size,
-		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
-{
-	if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
-	    !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
-	    dma_alloc_need_uncached(dev, attrs))
-		return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
-	return dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
-}
-
-void dma_direct_free(struct device *dev, size_t size,
-		void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs)
-{
-	if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
-	    !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
-	    dma_alloc_need_uncached(dev, attrs))
-		arch_dma_free(dev, size, cpu_addr, dma_addr, attrs);
-	else
-		dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs);
-}
-
 #if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
     defined(CONFIG_SWIOTLB)
 void dma_direct_sync_sg_for_device(struct device *dev,
diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
index 1281c0f0442bc5..fe11643ff9cc7b 100644
--- a/kernel/dma/pool.c
+++ b/kernel/dma/pool.c
@@ -115,7 +115,7 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
 #endif
 	/*
 	 * Memory in the atomic DMA pools must be unencrypted, the pools do not
-	 * shrink so no re-encryption occurs in dma_direct_free_pages().
+	 * shrink so no re-encryption occurs in dma_direct_free().
 	 */
 	ret = set_memory_decrypted((unsigned long)page_to_virt(page),
 				   1 << order);
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 07/12] dma-direct: lift gfp_t manipulation out of__dma_direct_alloc_pages
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
                   ` (5 preceding siblings ...)
  2020-09-08 16:47 ` [PATCH 06/12] dma-direct: remove dma_direct_{alloc,free}_pages Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-10 13:02   ` Robin Murphy
  2020-09-08 16:47 ` [PATCH 08/12] dma-direct: use phys_to_dma_direct in dma_direct_alloc Christoph Hellwig
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

Move the detailed gfp_t setup from __dma_direct_alloc_pages into the
caller to clean things up a little.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 kernel/dma/direct.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 1d564bea58571b..12e9f5f75dfe4b 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -108,7 +108,7 @@ static inline bool dma_should_free_from_pool(struct device *dev,
 }
 
 static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
-		gfp_t gfp, unsigned long attrs)
+		gfp_t gfp)
 {
 	int node = dev_to_node(dev);
 	struct page *page = NULL;
@@ -116,11 +116,6 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
 
 	WARN_ON_ONCE(!PAGE_ALIGNED(size));
 
-	if (attrs & DMA_ATTR_NO_WARN)
-		gfp |= __GFP_NOWARN;
-
-	/* we always manually zero the memory once we are done: */
-	gfp &= ~__GFP_ZERO;
 	gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
 					   &phys_limit);
 	page = dma_alloc_contiguous(dev, size, gfp);
@@ -164,6 +159,8 @@ void *dma_direct_alloc(struct device *dev, size_t size,
 		return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
 
 	size = PAGE_ALIGN(size);
+	if (attrs & DMA_ATTR_NO_WARN)
+		gfp |= __GFP_NOWARN;
 
 	if (dma_should_alloc_from_pool(dev, gfp, attrs)) {
 		u64 phys_mask;
@@ -177,7 +174,8 @@ void *dma_direct_alloc(struct device *dev, size_t size,
 		goto done;
 	}
 
-	page = __dma_direct_alloc_pages(dev, size, gfp, attrs);
+	/* we always manually zero the memory once we are done */
+	page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO);
 	if (!page)
 		return NULL;
 
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 08/12] dma-direct: use phys_to_dma_direct in dma_direct_alloc
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
                   ` (6 preceding siblings ...)
  2020-09-08 16:47 ` [PATCH 07/12] dma-direct: lift gfp_t manipulation out of__dma_direct_alloc_pages Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-10 13:03   ` Robin Murphy
  2020-09-08 16:47 ` [PATCH 09/12] dma-direct: remove __dma_to_phys Christoph Hellwig
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

Replace the currently open code copy.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 kernel/dma/direct.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 12e9f5f75dfe4b..57a6e7d7cf8f16 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -240,10 +240,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
 			goto out_encrypt_pages;
 	}
 done:
-	if (force_dma_unencrypted(dev))
-		*dma_handle = __phys_to_dma(dev, page_to_phys(page));
-	else
-		*dma_handle = phys_to_dma(dev, page_to_phys(page));
+	*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
 	return ret;
 
 out_encrypt_pages:
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 09/12] dma-direct: remove __dma_to_phys
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
                   ` (7 preceding siblings ...)
  2020-09-08 16:47 ` [PATCH 08/12] dma-direct: use phys_to_dma_direct in dma_direct_alloc Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-10 13:26   ` Robin Murphy
  2020-09-08 16:47 ` [PATCH 10/12] dma-direct: rename and cleanup __phys_to_dma Christoph Hellwig
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

There is no harm in just always clearing the SME encryption bit, while
significantly simplifying the interface.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm/include/asm/dma-direct.h      |  2 +-
 arch/mips/bmips/dma.c                  |  2 +-
 arch/mips/cavium-octeon/dma-octeon.c   |  2 +-
 arch/mips/include/asm/dma-direct.h     |  2 +-
 arch/mips/loongson2ef/fuloong-2e/dma.c |  2 +-
 arch/mips/loongson2ef/lemote-2f/dma.c  |  2 +-
 arch/mips/loongson64/dma.c             |  2 +-
 arch/mips/pci/pci-ar2315.c             |  2 +-
 arch/mips/pci/pci-xtalk-bridge.c       |  2 +-
 arch/mips/sgi-ip32/ip32-dma.c          |  2 +-
 arch/powerpc/include/asm/dma-direct.h  |  2 +-
 include/linux/dma-direct.h             | 14 +++++---------
 kernel/dma/direct.c                    |  6 +-----
 13 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h
index 7c3001a6a775bf..a8cee87a93e8ab 100644
--- a/arch/arm/include/asm/dma-direct.h
+++ b/arch/arm/include/asm/dma-direct.h
@@ -8,7 +8,7 @@ static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 	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)
+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;
diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c
index df56bf4179e347..ba2a5d33dfd3fa 100644
--- a/arch/mips/bmips/dma.c
+++ b/arch/mips/bmips/dma.c
@@ -52,7 +52,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t pa)
 	return pa;
 }
 
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
 {
 	struct bmips_dma_range *r;
 
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 14ea680d180e07..388b13ba2558c2 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -177,7 +177,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 	return paddr;
 }
 
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
 {
 #ifdef CONFIG_PCI
 	if (dev && dev_is_pci(dev))
diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h
index 14e352651ce946..8e178651c638c2 100644
--- a/arch/mips/include/asm/dma-direct.h
+++ b/arch/mips/include/asm/dma-direct.h
@@ -3,6 +3,6 @@
 #define _MIPS_DMA_DIRECT_H 1
 
 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);
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
 
 #endif /* _MIPS_DMA_DIRECT_H */
diff --git a/arch/mips/loongson2ef/fuloong-2e/dma.c b/arch/mips/loongson2ef/fuloong-2e/dma.c
index e122292bf6660a..83fadeb3fd7d56 100644
--- a/arch/mips/loongson2ef/fuloong-2e/dma.c
+++ b/arch/mips/loongson2ef/fuloong-2e/dma.c
@@ -6,7 +6,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 	return paddr | 0x80000000;
 }
 
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
 {
 	return dma_addr & 0x7fffffff;
 }
diff --git a/arch/mips/loongson2ef/lemote-2f/dma.c b/arch/mips/loongson2ef/lemote-2f/dma.c
index abf0e39d7e4696..302b43a14eee74 100644
--- a/arch/mips/loongson2ef/lemote-2f/dma.c
+++ b/arch/mips/loongson2ef/lemote-2f/dma.c
@@ -6,7 +6,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 	return paddr | 0x80000000;
 }
 
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
 {
 	if (dma_addr > 0x8fffffff)
 		return dma_addr;
diff --git a/arch/mips/loongson64/dma.c b/arch/mips/loongson64/dma.c
index dbfe6e82fddd1c..b3dc5d0bd2b113 100644
--- a/arch/mips/loongson64/dma.c
+++ b/arch/mips/loongson64/dma.c
@@ -13,7 +13,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 	return ((nid << 44) ^ paddr) | (nid << node_id_offset);
 }
 
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
 {
 	/* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
 	 * Loongson-3's 48bit address space and embed it into 40bit */
diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c
index 490953f515282a..d88395684f487d 100644
--- a/arch/mips/pci/pci-ar2315.c
+++ b/arch/mips/pci/pci-ar2315.c
@@ -175,7 +175,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 	return paddr + ar2315_dev_offset(dev);
 }
 
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
 {
 	return dma_addr - ar2315_dev_offset(dev);
 }
diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
index 9b3cc775c55e05..f1b37f32b55395 100644
--- a/arch/mips/pci/pci-xtalk-bridge.c
+++ b/arch/mips/pci/pci-xtalk-bridge.c
@@ -33,7 +33,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 	return bc->baddr + paddr;
 }
 
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
 {
 	return dma_addr & ~(0xffUL << 56);
 }
diff --git a/arch/mips/sgi-ip32/ip32-dma.c b/arch/mips/sgi-ip32/ip32-dma.c
index fa7b17cb53853e..160317294d97a9 100644
--- a/arch/mips/sgi-ip32/ip32-dma.c
+++ b/arch/mips/sgi-ip32/ip32-dma.c
@@ -27,7 +27,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 	return dma_addr;
 }
 
-phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
 {
 	phys_addr_t paddr = dma_addr & RAM_OFFSET_MASK;
 
diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
index abc154d784b078..95b09313d2a4cf 100644
--- a/arch/powerpc/include/asm/dma-direct.h
+++ b/arch/powerpc/include/asm/dma-direct.h
@@ -7,7 +7,7 @@ static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 	return paddr + dev->archdata.dma_offset;
 }
 
-static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
 {
 	return daddr - dev->archdata.dma_offset;
 }
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index 20eceb2e4f91f8..f00e262ab6b154 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -24,11 +24,12 @@ static inline dma_addr_t __phys_to_dma(struct device *dev, phys_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)
+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;
+	phys_addr_t paddr = (phys_addr_t)dev_addr +
+		((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
 
-	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
+	return __sme_clr(paddr);
 }
 #endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
 
@@ -44,7 +45,7 @@ static inline bool force_dma_unencrypted(struct device *dev)
 /*
  * If memory encryption is supported, phys_to_dma will set the memory encryption
  * bit in the DMA address, and dma_to_phys will clear it.  The raw __phys_to_dma
- * and __dma_to_phys versions should only be used on non-encrypted memory for
+ * version should only be used on non-encrypted memory for
  * special occasions like DMA coherent buffers.
  */
 static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
@@ -52,11 +53,6 @@ static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 	return __sme_set(__phys_to_dma(dev, paddr));
 }
 
-static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
-{
-	return __sme_clr(__dma_to_phys(dev, daddr));
-}
-
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size,
 		bool is_ram)
 {
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 57a6e7d7cf8f16..bfb479c8a370fa 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -48,11 +48,6 @@ static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
 {
 	u64 dma_limit = min_not_zero(dma_mask, dev->bus_dma_limit);
 
-	if (force_dma_unencrypted(dev))
-		*phys_limit = __dma_to_phys(dev, dma_limit);
-	else
-		*phys_limit = dma_to_phys(dev, dma_limit);
-
 	/*
 	 * Optimistically try the zone that the physical address mask falls
 	 * into first.  If that returns memory that isn't actually addressable
@@ -61,6 +56,7 @@ static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
 	 * Note that GFP_DMA32 and GFP_DMA are no ops without the corresponding
 	 * zones.
 	 */
+	*phys_limit = dma_to_phys(dev, dma_limit);
 	if (*phys_limit <= DMA_BIT_MASK(zone_dma_bits))
 		return GFP_DMA;
 	if (*phys_limit <= DMA_BIT_MASK(32))
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 10/12] dma-direct: rename and cleanup __phys_to_dma
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
                   ` (8 preceding siblings ...)
  2020-09-08 16:47 ` [PATCH 09/12] dma-direct: remove __dma_to_phys Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-10 13:30   ` Robin Murphy
  2020-09-08 16:47 ` [PATCH 11/12] dma-mapping: move dma_common_{mmap, get_sgtable} out of mapping.c Christoph Hellwig
  2020-09-08 16:47 ` [PATCH 12/12] dma-mapping: move the dma_declare_coherent_memory documentation Christoph Hellwig
  11 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

The __phys_to_dma vs phys_to_dma distinction isn't exactly obvious.  Try
to improve the situation by renaming __phys_to_dma to
phys_to_dma_unencryped, and not forcing architectures that want to
override phys_to_dma to actually provide __phys_to_dma.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm/include/asm/dma-direct.h      |  2 +-
 arch/mips/bmips/dma.c                  |  2 +-
 arch/mips/cavium-octeon/dma-octeon.c   |  2 +-
 arch/mips/include/asm/dma-direct.h     |  2 +-
 arch/mips/loongson2ef/fuloong-2e/dma.c |  2 +-
 arch/mips/loongson2ef/lemote-2f/dma.c  |  2 +-
 arch/mips/loongson64/dma.c             |  2 +-
 arch/mips/pci/pci-ar2315.c             |  2 +-
 arch/mips/pci/pci-xtalk-bridge.c       |  2 +-
 arch/mips/sgi-ip32/ip32-dma.c          |  2 +-
 arch/powerpc/include/asm/dma-direct.h  |  2 +-
 drivers/iommu/intel/iommu.c            |  2 +-
 include/linux/dma-direct.h             | 28 +++++++++++++++-----------
 kernel/dma/direct.c                    |  8 ++++----
 kernel/dma/swiotlb.c                   |  4 ++--
 15 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h
index a8cee87a93e8ab..bca0de56753439 100644
--- a/arch/arm/include/asm/dma-direct.h
+++ b/arch/arm/include/asm/dma-direct.h
@@ -2,7 +2,7 @@
 #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)
+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;
diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c
index ba2a5d33dfd3fa..49061b870680b9 100644
--- a/arch/mips/bmips/dma.c
+++ b/arch/mips/bmips/dma.c
@@ -40,7 +40,7 @@ static struct bmips_dma_range *bmips_dma_ranges;
 
 #define FLUSH_RAC		0x100
 
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t pa)
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t pa)
 {
 	struct bmips_dma_range *r;
 
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 388b13ba2558c2..232fa1017b1ec9 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -168,7 +168,7 @@ void __init octeon_pci_dma_init(void)
 }
 #endif /* CONFIG_PCI */
 
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 #ifdef CONFIG_PCI
 	if (dev && dev_is_pci(dev))
diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h
index 8e178651c638c2..9a640118316c9d 100644
--- a/arch/mips/include/asm/dma-direct.h
+++ b/arch/mips/include/asm/dma-direct.h
@@ -2,7 +2,7 @@
 #ifndef _MIPS_DMA_DIRECT_H
 #define _MIPS_DMA_DIRECT_H 1
 
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
+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);
 
 #endif /* _MIPS_DMA_DIRECT_H */
diff --git a/arch/mips/loongson2ef/fuloong-2e/dma.c b/arch/mips/loongson2ef/fuloong-2e/dma.c
index 83fadeb3fd7d56..cea167d8aba8db 100644
--- a/arch/mips/loongson2ef/fuloong-2e/dma.c
+++ b/arch/mips/loongson2ef/fuloong-2e/dma.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/dma-direct.h>
 
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 	return paddr | 0x80000000;
 }
diff --git a/arch/mips/loongson2ef/lemote-2f/dma.c b/arch/mips/loongson2ef/lemote-2f/dma.c
index 302b43a14eee74..3c9e994563578c 100644
--- a/arch/mips/loongson2ef/lemote-2f/dma.c
+++ b/arch/mips/loongson2ef/lemote-2f/dma.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/dma-direct.h>
 
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 	return paddr | 0x80000000;
 }
diff --git a/arch/mips/loongson64/dma.c b/arch/mips/loongson64/dma.c
index b3dc5d0bd2b113..364f2f27c8723f 100644
--- a/arch/mips/loongson64/dma.c
+++ b/arch/mips/loongson64/dma.c
@@ -4,7 +4,7 @@
 #include <linux/swiotlb.h>
 #include <boot_param.h>
 
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 	/* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
 	 * Loongson-3's 48bit address space and embed it into 40bit */
diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c
index d88395684f487d..cef4a47ab06311 100644
--- a/arch/mips/pci/pci-ar2315.c
+++ b/arch/mips/pci/pci-ar2315.c
@@ -170,7 +170,7 @@ static inline dma_addr_t ar2315_dev_offset(struct device *dev)
 	return 0;
 }
 
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 	return paddr + ar2315_dev_offset(dev);
 }
diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
index f1b37f32b55395..50f7d42cca5a78 100644
--- a/arch/mips/pci/pci-xtalk-bridge.c
+++ b/arch/mips/pci/pci-xtalk-bridge.c
@@ -25,7 +25,7 @@
 /*
  * Common phys<->dma mapping for platforms using pci xtalk bridge
  */
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct bridge_controller *bc = BRIDGE_CONTROLLER(pdev->bus);
diff --git a/arch/mips/sgi-ip32/ip32-dma.c b/arch/mips/sgi-ip32/ip32-dma.c
index 160317294d97a9..20c6da9d76bc5e 100644
--- a/arch/mips/sgi-ip32/ip32-dma.c
+++ b/arch/mips/sgi-ip32/ip32-dma.c
@@ -18,7 +18,7 @@
 
 #define RAM_OFFSET_MASK 0x3fffffffUL
 
-dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 	dma_addr_t dma_addr = paddr & RAM_OFFSET_MASK;
 
diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
index 95b09313d2a4cf..128304cbee1d87 100644
--- a/arch/powerpc/include/asm/dma-direct.h
+++ b/arch/powerpc/include/asm/dma-direct.h
@@ -2,7 +2,7 @@
 #ifndef ASM_POWERPC_DMA_DIRECT_H
 #define ASM_POWERPC_DMA_DIRECT_H 1
 
-static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 	return paddr + dev->archdata.dma_offset;
 }
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index f8177c59d229a6..7983c13b9eef7d 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -3736,7 +3736,7 @@ bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size,
 	 */
 	if (!IS_ALIGNED(paddr | size, VTD_PAGE_SIZE)) {
 		tlb_addr = swiotlb_tbl_map_single(dev,
-				__phys_to_dma(dev, io_tlb_start),
+				phys_to_dma_unencrypted(dev, io_tlb_start),
 				paddr, size, aligned_size, dir, attrs);
 		if (tlb_addr == DMA_MAPPING_ERROR) {
 			goto swiotlb_error;
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index f00e262ab6b154..805010ea5346f9 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -16,14 +16,29 @@ extern unsigned int zone_dma_bits;
 
 #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
 #include <asm/dma-direct.h>
+#ifndef phys_to_dma_unencrypted
+#define phys_to_dma_unencrypted		phys_to_dma
+#endif
 #else
-static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+static inline dma_addr_t phys_to_dma_unencrypted(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);
 }
 
+/*
+ * If memory encryption is supported, phys_to_dma will set the memory encryption
+ * bit in the DMA address, and dma_to_phys will clear it.
+ * phys_to_dma_unencrypted is for use on special unencrypted memory like swiotlb
+ * buffers.
+ */
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	return __sme_set(phys_to_dma_unencrypted(dev, paddr));
+}
+
 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 +
@@ -42,17 +57,6 @@ static inline bool force_dma_unencrypted(struct device *dev)
 }
 #endif /* CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED */
 
-/*
- * If memory encryption is supported, phys_to_dma will set the memory encryption
- * bit in the DMA address, and dma_to_phys will clear it.  The raw __phys_to_dma
- * version should only be used on non-encrypted memory for
- * special occasions like DMA coherent buffers.
- */
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
-{
-	return __sme_set(__phys_to_dma(dev, paddr));
-}
-
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size,
 		bool is_ram)
 {
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index bfb479c8a370fa..54db9cfdaecc6d 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -25,7 +25,7 @@ static inline dma_addr_t phys_to_dma_direct(struct device *dev,
 		phys_addr_t phys)
 {
 	if (force_dma_unencrypted(dev))
-		return __phys_to_dma(dev, phys);
+		return phys_to_dma_unencrypted(dev, phys);
 	return phys_to_dma(dev, phys);
 }
 
@@ -438,13 +438,13 @@ int dma_direct_supported(struct device *dev, u64 mask)
 		return 1;
 
 	/*
-	 * This check needs to be against the actual bit mask value, so
-	 * use __phys_to_dma() here so that the SME encryption mask isn't
+	 * This check needs to be against the actual bit mask value, so use
+	 * phys_to_dma_unencrypted() here so that the SME encryption mask isn't
 	 * part of the check.
 	 */
 	if (IS_ENABLED(CONFIG_ZONE_DMA))
 		min_mask = min_t(u64, min_mask, DMA_BIT_MASK(zone_dma_bits));
-	return mask >= __phys_to_dma(dev, min_mask);
+	return mask >= phys_to_dma_unencrypted(dev, min_mask);
 }
 
 size_t dma_direct_max_mapping_size(struct device *dev)
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index c19379fabd200e..4ea72d145cd27d 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -670,13 +670,13 @@ dma_addr_t swiotlb_map(struct device *dev, phys_addr_t paddr, size_t size,
 			      swiotlb_force);
 
 	swiotlb_addr = swiotlb_tbl_map_single(dev,
-			__phys_to_dma(dev, io_tlb_start),
+			phys_to_dma_unencrypted(dev, io_tlb_start),
 			paddr, size, size, dir, attrs);
 	if (swiotlb_addr == (phys_addr_t)DMA_MAPPING_ERROR)
 		return DMA_MAPPING_ERROR;
 
 	/* Ensure that the address returned is DMA'ble */
-	dma_addr = __phys_to_dma(dev, swiotlb_addr);
+	dma_addr = phys_to_dma_unencrypted(dev, swiotlb_addr);
 	if (unlikely(!dma_capable(dev, dma_addr, size, true))) {
 		swiotlb_tbl_unmap_single(dev, swiotlb_addr, size, size, dir,
 			attrs | DMA_ATTR_SKIP_CPU_SYNC);
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 11/12] dma-mapping: move dma_common_{mmap, get_sgtable} out of mapping.c
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
                   ` (9 preceding siblings ...)
  2020-09-08 16:47 ` [PATCH 10/12] dma-direct: rename and cleanup __phys_to_dma Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-10 13:34   ` Robin Murphy
  2020-09-08 16:47 ` [PATCH 12/12] dma-mapping: move the dma_declare_coherent_memory documentation Christoph Hellwig
  11 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

Add a new file that contains helpera for misc DMA ops, which is only
built when CONFIG_DMA_OPS is set.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 kernel/dma/Makefile      |  1 +
 kernel/dma/mapping.c     | 47 +-----------------------------------
 kernel/dma/ops_helpers.c | 51 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 46 deletions(-)
 create mode 100644 kernel/dma/ops_helpers.c

diff --git a/kernel/dma/Makefile b/kernel/dma/Makefile
index 32c7c1942bbd6c..dc755ab68aabf9 100644
--- a/kernel/dma/Makefile
+++ b/kernel/dma/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_HAS_DMA)			+= mapping.o direct.o
+obj-$(CONFIG_DMA_OPS)			+= ops_helpers.o
 obj-$(CONFIG_DMA_OPS)			+= dummy.o
 obj-$(CONFIG_DMA_CMA)			+= contiguous.o
 obj-$(CONFIG_DMA_DECLARE_COHERENT)	+= coherent.o
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 0d129421e75fc8..848c95c27d79ff 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -8,7 +8,7 @@
 #include <linux/memblock.h> /* for max_pfn */
 #include <linux/acpi.h>
 #include <linux/dma-direct.h>
-#include <linux/dma-noncoherent.h>
+#include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <linux/gfp.h>
 #include <linux/of_device.h>
@@ -295,22 +295,6 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 }
 EXPORT_SYMBOL(dma_sync_sg_for_device);
 
-/*
- * Create scatter-list for the already allocated DMA buffer.
- */
-int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		 unsigned long attrs)
-{
-	struct page *page = virt_to_page(cpu_addr);
-	int ret;
-
-	ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
-	if (!ret)
-		sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
-	return ret;
-}
-
 /*
  * The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
  * that the intention is to allow exporting memory allocated via the
@@ -358,35 +342,6 @@ pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs)
 }
 #endif /* CONFIG_MMU */
 
-/*
- * Create userspace mapping for the DMA-coherent memory.
- */
-int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
-		void *cpu_addr, dma_addr_t dma_addr, size_t size,
-		unsigned long attrs)
-{
-#ifdef CONFIG_MMU
-	unsigned long user_count = vma_pages(vma);
-	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
-	unsigned long off = vma->vm_pgoff;
-	int ret = -ENXIO;
-
-	vma->vm_page_prot = dma_pgprot(dev, vma->vm_page_prot, attrs);
-
-	if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
-		return ret;
-
-	if (off >= count || user_count > count - off)
-		return -ENXIO;
-
-	return remap_pfn_range(vma, vma->vm_start,
-			page_to_pfn(virt_to_page(cpu_addr)) + vma->vm_pgoff,
-			user_count << PAGE_SHIFT, vma->vm_page_prot);
-#else
-	return -ENXIO;
-#endif /* CONFIG_MMU */
-}
-
 /**
  * dma_can_mmap - check if a given device supports dma_mmap_*
  * @dev: device to check
diff --git a/kernel/dma/ops_helpers.c b/kernel/dma/ops_helpers.c
new file mode 100644
index 00000000000000..e443c69be4299f
--- /dev/null
+++ b/kernel/dma/ops_helpers.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Helpers for DMA ops implementations.  These generally rely on the fact that
+ * the allocated memory contains normal pages in the direct kernel mapping.
+ */
+#include <linux/dma-noncoherent.h>
+
+/*
+ * Create scatter-list for the already allocated DMA buffer.
+ */
+int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
+		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
+		 unsigned long attrs)
+{
+	struct page *page = virt_to_page(cpu_addr);
+	int ret;
+
+	ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
+	if (!ret)
+		sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
+	return ret;
+}
+
+/*
+ * Create userspace mapping for the DMA-coherent memory.
+ */
+int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
+		void *cpu_addr, dma_addr_t dma_addr, size_t size,
+		unsigned long attrs)
+{
+#ifdef CONFIG_MMU
+	unsigned long user_count = vma_pages(vma);
+	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+	unsigned long off = vma->vm_pgoff;
+	int ret = -ENXIO;
+
+	vma->vm_page_prot = dma_pgprot(dev, vma->vm_page_prot, attrs);
+
+	if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
+		return ret;
+
+	if (off >= count || user_count > count - off)
+		return -ENXIO;
+
+	return remap_pfn_range(vma, vma->vm_start,
+			page_to_pfn(virt_to_page(cpu_addr)) + vma->vm_pgoff,
+			user_count << PAGE_SHIFT, vma->vm_page_prot);
+#else
+	return -ENXIO;
+#endif /* CONFIG_MMU */
+}
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 12/12] dma-mapping: move the dma_declare_coherent_memory documentation
  2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
                   ` (10 preceding siblings ...)
  2020-09-08 16:47 ` [PATCH 11/12] dma-mapping: move dma_common_{mmap, get_sgtable} out of mapping.c Christoph Hellwig
@ 2020-09-08 16:47 ` Christoph Hellwig
  2020-09-10 13:51   ` Robin Murphy
  11 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-08 16:47 UTC (permalink / raw)
  To: Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

dma_declare_coherent_memory should not be in a DMA API guide aimed
at driver writers (that is consumers of the API).  Move it to a comment
near the function instead.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 Documentation/core-api/dma-api.rst | 24 ------------------------
 kernel/dma/coherent.c              | 17 +++++++++++++++++
 2 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/Documentation/core-api/dma-api.rst b/Documentation/core-api/dma-api.rst
index 3b3abbbb4b9a6f..90239348b30f6f 100644
--- a/Documentation/core-api/dma-api.rst
+++ b/Documentation/core-api/dma-api.rst
@@ -586,30 +586,6 @@ the DMA_ATTR_NON_CONSISTENT flag starting at virtual address vaddr and
 continuing on for size.  Again, you *must* observe the cache line
 boundaries when doing this.
 
-::
-
-	int
-	dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
-				    dma_addr_t device_addr, size_t size);
-
-Declare region of memory to be handed out by dma_alloc_coherent() when
-it's asked for coherent memory for this device.
-
-phys_addr is the CPU physical address to which the memory is currently
-assigned (this will be ioremapped so the CPU can access the region).
-
-device_addr is the DMA address the device needs to be programmed
-with to actually address this memory (this will be handed out as the
-dma_addr_t in dma_alloc_coherent()).
-
-size is the size of the area (must be multiples of PAGE_SIZE).
-
-As a simplification for the platforms, only *one* such region of
-memory may be declared per device.
-
-For reasons of efficiency, most platforms choose to track the declared
-region only at the granularity of a page.  For smaller allocations,
-you should use the dma_pool() API.
 
 Part III - Debug drivers use of the DMA-API
 -------------------------------------------
diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index 2a0c4985f38e41..f85d14bbfcbe03 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -107,6 +107,23 @@ static int dma_assign_coherent_memory(struct device *dev,
 	return 0;
 }
 
+/*
+ * Declare a region of memory to be handed out by dma_alloc_coherent() when it
+ * is asked for coherent memory for this device.  This shall only be used
+ * from platform code, usually based on the device tree description.
+ * 
+ * phys_addr is the CPU physical address to which the memory is currently
+ * assigned (this will be ioremapped so the CPU can access the region).
+ *
+ * device_addr is the DMA address the device needs to be programmed with to
+ * actually address this memory (this will be handed out as the dma_addr_t in
+ * dma_alloc_coherent()).
+ *
+ * size is the size of the area (must be a multiple of PAGE_SIZE).
+ *
+ * As a simplification for the platforms, only *one* such region of memory may
+ * be declared per device.
+ */
 int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
 				dma_addr_t device_addr, size_t size)
 {
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies
  2020-09-08 16:47 ` [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies Christoph Hellwig
@ 2020-09-08 18:04   ` Sergei Shtylyov
  2020-09-11  7:10     ` Christoph Hellwig
  2020-09-10 12:55   ` Robin Murphy
  1 sibling, 1 reply; 27+ messages in thread
From: Sergei Shtylyov @ 2020-09-08 18:04 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-kernel, linux-mips, Robin Murphy

Hello!

On 9/8/20 7:47 PM, Christoph Hellwig wrote:

> Driver that select DMA_OPS need to depend on HAS_DMA support to
> work.  The vop driver was missing that dependency, so add it, and also
> add a nother depends in DMA_OPS itself.  That won't fix the issue due

   Another? :-)

> to how the Kconfig dependencies work, but at least produce a warning
> about unmet dependencies.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
[...]

MBR, Sergei
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies
  2020-09-08 16:47 ` [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies Christoph Hellwig
  2020-09-08 18:04   ` Sergei Shtylyov
@ 2020-09-10 12:55   ` Robin Murphy
  2020-09-11  7:09     ` Christoph Hellwig
  1 sibling, 1 reply; 27+ messages in thread
From: Robin Murphy @ 2020-09-10 12:55 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-mips, linux-kernel

On 2020-09-08 17:47, Christoph Hellwig wrote:
> Driver that select DMA_OPS need to depend on HAS_DMA support to
> work.  The vop driver was missing that dependency, so add it, and also
> add a nother depends in DMA_OPS itself.  That won't fix the issue due
> to how the Kconfig dependencies work, but at least produce a warning
> about unmet dependencies.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   drivers/misc/mic/Kconfig | 1 +
>   kernel/dma/Kconfig       | 1 +
>   2 files changed, 2 insertions(+)
> 
> diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
> index b9bb086785db48..8a7c2c5711d5f4 100644
> --- a/drivers/misc/mic/Kconfig
> +++ b/drivers/misc/mic/Kconfig
> @@ -35,6 +35,7 @@ config SCIF_BUS
>   
>   config VOP_BUS
>   	tristate "VOP Bus Driver"
> +	depends on HAS_DMA
>   	select DMA_OPS

AFAICS all three of these bus drivers are only proxying a struct 
dma_map_ops * pointer around, so if they used the set_dma_ops() helper 
they shouldn't even need these selects at all. Only INTEL_MIC_HOST 
appears to have a logical dependency on DMA_OPS for actual functionality.

However, I have a vague feeling you might not be fond of those dma_ops 
helpers, and I have no great objection to this one-liner as-is, so 
(modulo the couple of commit message typos),

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

(of course the hunk below is unquestionably OK)

Robin.

>   	help
>   	  This option is selected by any driver which registers a
> diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
> index 0ddfb5510fe45f..e7b801649f6574 100644
> --- a/kernel/dma/Kconfig
> +++ b/kernel/dma/Kconfig
> @@ -9,6 +9,7 @@ config HAS_DMA
>   	default y
>   
>   config DMA_OPS
> +	depends on HAS_DMA
>   	bool
>   
>   #
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 06/12] dma-direct: remove dma_direct_{alloc,free}_pages
  2020-09-08 16:47 ` [PATCH 06/12] dma-direct: remove dma_direct_{alloc,free}_pages Christoph Hellwig
@ 2020-09-10 12:57   ` Robin Murphy
  0 siblings, 0 replies; 27+ messages in thread
From: Robin Murphy @ 2020-09-10 12:57 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-mips, linux-ia64, linux-kernel, linux-doc

On 2020-09-08 17:47, Christoph Hellwig wrote:
> Just merge these helpers into the main dma_direct_{alloc,free} routines,
> as the additional checks are always false for the two callers.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   arch/x86/kernel/amd_gart_64.c |  6 +++---
>   include/linux/dma-direct.h    |  4 ----
>   kernel/dma/direct.c           | 39 ++++++++++++++---------------------
>   kernel/dma/pool.c             |  2 +-
>   4 files changed, 19 insertions(+), 32 deletions(-)
> 
> diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
> index bccc5357bffd6c..153374b996a279 100644
> --- a/arch/x86/kernel/amd_gart_64.c
> +++ b/arch/x86/kernel/amd_gart_64.c
> @@ -467,7 +467,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
>   {
>   	void *vaddr;
>   
> -	vaddr = dma_direct_alloc_pages(dev, size, dma_addr, flag, attrs);
> +	vaddr = dma_direct_alloc(dev, size, dma_addr, flag, attrs);
>   	if (!vaddr ||
>   	    !force_iommu || dev->coherent_dma_mask <= DMA_BIT_MASK(24))
>   		return vaddr;
> @@ -479,7 +479,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
>   		goto out_free;
>   	return vaddr;
>   out_free:
> -	dma_direct_free_pages(dev, size, vaddr, *dma_addr, attrs);
> +	dma_direct_free(dev, size, vaddr, *dma_addr, attrs);
>   	return NULL;
>   }
>   
> @@ -489,7 +489,7 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr,
>   		   dma_addr_t dma_addr, unsigned long attrs)
>   {
>   	gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, 0);
> -	dma_direct_free_pages(dev, size, vaddr, dma_addr, attrs);
> +	dma_direct_free(dev, size, vaddr, dma_addr, attrs);
>   }
>   
>   static int no_agp;
> diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
> index 95e3e28bd93f47..20eceb2e4f91f8 100644
> --- a/include/linux/dma-direct.h
> +++ b/include/linux/dma-direct.h
> @@ -77,10 +77,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);
> -void *dma_direct_alloc_pages(struct device *dev, size_t size,
> -		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs);
> -void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
> -		dma_addr_t dma_addr, unsigned long attrs);
>   int dma_direct_get_sgtable(struct device *dev, struct sg_table *sgt,
>   		void *cpu_addr, dma_addr_t dma_addr, size_t size,
>   		unsigned long attrs);
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index 949c1cbf08b2d5..1d564bea58571b 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -151,13 +151,18 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
>   	return page;
>   }
>   
> -void *dma_direct_alloc_pages(struct device *dev, size_t size,
> +void *dma_direct_alloc(struct device *dev, size_t size,
>   		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
>   {
>   	struct page *page;
>   	void *ret;
>   	int err;
>   
> +	if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
> +	    !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
> +	    dma_alloc_need_uncached(dev, attrs))
> +		return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
> +
>   	size = PAGE_ALIGN(size);
>   
>   	if (dma_should_alloc_from_pool(dev, gfp, attrs)) {
> @@ -256,11 +261,18 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size,
>   	return NULL;
>   }
>   
> -void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
> -		dma_addr_t dma_addr, unsigned long attrs)
> +void dma_direct_free(struct device *dev, size_t size,
> +		void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs)
>   {
>   	unsigned int page_order = get_order(size);
>   
> +	if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
> +	    !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
> +	    dma_alloc_need_uncached(dev, attrs)) {
> +		arch_dma_free(dev, size, cpu_addr, dma_addr, attrs);
> +		return;
> +	}
> +
>   	/* If cpu_addr is not from an atomic pool, dma_free_from_pool() fails */
>   	if (dma_should_free_from_pool(dev, attrs) &&
>   	    dma_free_from_pool(dev, cpu_addr, PAGE_ALIGN(size)))
> @@ -284,27 +296,6 @@ void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
>   	dma_free_contiguous(dev, dma_direct_to_page(dev, dma_addr), size);
>   }
>   
> -void *dma_direct_alloc(struct device *dev, size_t size,
> -		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
> -{
> -	if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
> -	    !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
> -	    dma_alloc_need_uncached(dev, attrs))
> -		return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
> -	return dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
> -}
> -
> -void dma_direct_free(struct device *dev, size_t size,
> -		void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs)
> -{
> -	if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
> -	    !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
> -	    dma_alloc_need_uncached(dev, attrs))
> -		arch_dma_free(dev, size, cpu_addr, dma_addr, attrs);
> -	else
> -		dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs);
> -}
> -
>   #if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
>       defined(CONFIG_SWIOTLB)
>   void dma_direct_sync_sg_for_device(struct device *dev,
> diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
> index 1281c0f0442bc5..fe11643ff9cc7b 100644
> --- a/kernel/dma/pool.c
> +++ b/kernel/dma/pool.c
> @@ -115,7 +115,7 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
>   #endif
>   	/*
>   	 * Memory in the atomic DMA pools must be unencrypted, the pools do not
> -	 * shrink so no re-encryption occurs in dma_direct_free_pages().
> +	 * shrink so no re-encryption occurs in dma_direct_free().
>   	 */
>   	ret = set_memory_decrypted((unsigned long)page_to_virt(page),
>   				   1 << order);
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 07/12] dma-direct: lift gfp_t manipulation out of__dma_direct_alloc_pages
  2020-09-08 16:47 ` [PATCH 07/12] dma-direct: lift gfp_t manipulation out of__dma_direct_alloc_pages Christoph Hellwig
@ 2020-09-10 13:02   ` Robin Murphy
  0 siblings, 0 replies; 27+ messages in thread
From: Robin Murphy @ 2020-09-10 13:02 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-mips, linux-ia64, linux-kernel, linux-doc

On 2020-09-08 17:47, Christoph Hellwig wrote:
> Move the detailed gfp_t setup from __dma_direct_alloc_pages into the
> caller to clean things up a little.

Other than a mild nitpick that it might be nicer to spend one extra line 
to keep both gfp adjustments next to each other,

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   kernel/dma/direct.c | 12 +++++-------
>   1 file changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index 1d564bea58571b..12e9f5f75dfe4b 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -108,7 +108,7 @@ static inline bool dma_should_free_from_pool(struct device *dev,
>   }
>   
>   static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
> -		gfp_t gfp, unsigned long attrs)
> +		gfp_t gfp)
>   {
>   	int node = dev_to_node(dev);
>   	struct page *page = NULL;
> @@ -116,11 +116,6 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
>   
>   	WARN_ON_ONCE(!PAGE_ALIGNED(size));
>   
> -	if (attrs & DMA_ATTR_NO_WARN)
> -		gfp |= __GFP_NOWARN;
> -
> -	/* we always manually zero the memory once we are done: */
> -	gfp &= ~__GFP_ZERO;
>   	gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
>   					   &phys_limit);
>   	page = dma_alloc_contiguous(dev, size, gfp);
> @@ -164,6 +159,8 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>   		return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
>   
>   	size = PAGE_ALIGN(size);
> +	if (attrs & DMA_ATTR_NO_WARN)
> +		gfp |= __GFP_NOWARN;
>   
>   	if (dma_should_alloc_from_pool(dev, gfp, attrs)) {
>   		u64 phys_mask;
> @@ -177,7 +174,8 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>   		goto done;
>   	}
>   
> -	page = __dma_direct_alloc_pages(dev, size, gfp, attrs);
> +	/* we always manually zero the memory once we are done */
> +	page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO);
>   	if (!page)
>   		return NULL;
>   
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 08/12] dma-direct: use phys_to_dma_direct in dma_direct_alloc
  2020-09-08 16:47 ` [PATCH 08/12] dma-direct: use phys_to_dma_direct in dma_direct_alloc Christoph Hellwig
@ 2020-09-10 13:03   ` Robin Murphy
  0 siblings, 0 replies; 27+ messages in thread
From: Robin Murphy @ 2020-09-10 13:03 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-mips, linux-kernel

On 2020-09-08 17:47, Christoph Hellwig wrote:
> Replace the currently open code copy.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   kernel/dma/direct.c | 5 +----
>   1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index 12e9f5f75dfe4b..57a6e7d7cf8f16 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -240,10 +240,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>   			goto out_encrypt_pages;
>   	}
>   done:
> -	if (force_dma_unencrypted(dev))
> -		*dma_handle = __phys_to_dma(dev, page_to_phys(page));
> -	else
> -		*dma_handle = phys_to_dma(dev, page_to_phys(page));
> +	*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
>   	return ret;
>   
>   out_encrypt_pages:
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 09/12] dma-direct: remove __dma_to_phys
  2020-09-08 16:47 ` [PATCH 09/12] dma-direct: remove __dma_to_phys Christoph Hellwig
@ 2020-09-10 13:26   ` Robin Murphy
  2020-09-11  7:14     ` Christoph Hellwig
  0 siblings, 1 reply; 27+ messages in thread
From: Robin Murphy @ 2020-09-10 13:26 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-mips, linux-kernel

On 2020-09-08 17:47, Christoph Hellwig wrote:
> There is no harm in just always clearing the SME encryption bit, while
> significantly simplifying the interface.

After a 10-minute diversion into "but hang on, force_dma_unencrypted() 
is meaningful on PPC and S390 too..." before realising that it all does 
just come back to __sme_clr(), which is indeed a no-op for everyone 
other than AMD, any simplification of this mess is indeed welcome :)

Unless I've massively misunderstood how SME is supposed to work,

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   arch/arm/include/asm/dma-direct.h      |  2 +-
>   arch/mips/bmips/dma.c                  |  2 +-
>   arch/mips/cavium-octeon/dma-octeon.c   |  2 +-
>   arch/mips/include/asm/dma-direct.h     |  2 +-
>   arch/mips/loongson2ef/fuloong-2e/dma.c |  2 +-
>   arch/mips/loongson2ef/lemote-2f/dma.c  |  2 +-
>   arch/mips/loongson64/dma.c             |  2 +-
>   arch/mips/pci/pci-ar2315.c             |  2 +-
>   arch/mips/pci/pci-xtalk-bridge.c       |  2 +-
>   arch/mips/sgi-ip32/ip32-dma.c          |  2 +-
>   arch/powerpc/include/asm/dma-direct.h  |  2 +-
>   include/linux/dma-direct.h             | 14 +++++---------
>   kernel/dma/direct.c                    |  6 +-----
>   13 files changed, 17 insertions(+), 25 deletions(-)
> 
> diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h
> index 7c3001a6a775bf..a8cee87a93e8ab 100644
> --- a/arch/arm/include/asm/dma-direct.h
> +++ b/arch/arm/include/asm/dma-direct.h
> @@ -8,7 +8,7 @@ static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	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)
> +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;
> diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c
> index df56bf4179e347..ba2a5d33dfd3fa 100644
> --- a/arch/mips/bmips/dma.c
> +++ b/arch/mips/bmips/dma.c
> @@ -52,7 +52,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t pa)
>   	return pa;
>   }
>   
> -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
> +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
>   {
>   	struct bmips_dma_range *r;
>   
> diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
> index 14ea680d180e07..388b13ba2558c2 100644
> --- a/arch/mips/cavium-octeon/dma-octeon.c
> +++ b/arch/mips/cavium-octeon/dma-octeon.c
> @@ -177,7 +177,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	return paddr;
>   }
>   
> -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
> +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
>   {
>   #ifdef CONFIG_PCI
>   	if (dev && dev_is_pci(dev))
> diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h
> index 14e352651ce946..8e178651c638c2 100644
> --- a/arch/mips/include/asm/dma-direct.h
> +++ b/arch/mips/include/asm/dma-direct.h
> @@ -3,6 +3,6 @@
>   #define _MIPS_DMA_DIRECT_H 1
>   
>   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);
> +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
>   
>   #endif /* _MIPS_DMA_DIRECT_H */
> diff --git a/arch/mips/loongson2ef/fuloong-2e/dma.c b/arch/mips/loongson2ef/fuloong-2e/dma.c
> index e122292bf6660a..83fadeb3fd7d56 100644
> --- a/arch/mips/loongson2ef/fuloong-2e/dma.c
> +++ b/arch/mips/loongson2ef/fuloong-2e/dma.c
> @@ -6,7 +6,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	return paddr | 0x80000000;
>   }
>   
> -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
> +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
>   {
>   	return dma_addr & 0x7fffffff;
>   }
> diff --git a/arch/mips/loongson2ef/lemote-2f/dma.c b/arch/mips/loongson2ef/lemote-2f/dma.c
> index abf0e39d7e4696..302b43a14eee74 100644
> --- a/arch/mips/loongson2ef/lemote-2f/dma.c
> +++ b/arch/mips/loongson2ef/lemote-2f/dma.c
> @@ -6,7 +6,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	return paddr | 0x80000000;
>   }
>   
> -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
> +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
>   {
>   	if (dma_addr > 0x8fffffff)
>   		return dma_addr;
> diff --git a/arch/mips/loongson64/dma.c b/arch/mips/loongson64/dma.c
> index dbfe6e82fddd1c..b3dc5d0bd2b113 100644
> --- a/arch/mips/loongson64/dma.c
> +++ b/arch/mips/loongson64/dma.c
> @@ -13,7 +13,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	return ((nid << 44) ^ paddr) | (nid << node_id_offset);
>   }
>   
> -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
> +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
>   {
>   	/* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
>   	 * Loongson-3's 48bit address space and embed it into 40bit */
> diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c
> index 490953f515282a..d88395684f487d 100644
> --- a/arch/mips/pci/pci-ar2315.c
> +++ b/arch/mips/pci/pci-ar2315.c
> @@ -175,7 +175,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	return paddr + ar2315_dev_offset(dev);
>   }
>   
> -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
> +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
>   {
>   	return dma_addr - ar2315_dev_offset(dev);
>   }
> diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
> index 9b3cc775c55e05..f1b37f32b55395 100644
> --- a/arch/mips/pci/pci-xtalk-bridge.c
> +++ b/arch/mips/pci/pci-xtalk-bridge.c
> @@ -33,7 +33,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	return bc->baddr + paddr;
>   }
>   
> -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
> +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
>   {
>   	return dma_addr & ~(0xffUL << 56);
>   }
> diff --git a/arch/mips/sgi-ip32/ip32-dma.c b/arch/mips/sgi-ip32/ip32-dma.c
> index fa7b17cb53853e..160317294d97a9 100644
> --- a/arch/mips/sgi-ip32/ip32-dma.c
> +++ b/arch/mips/sgi-ip32/ip32-dma.c
> @@ -27,7 +27,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	return dma_addr;
>   }
>   
> -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
> +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
>   {
>   	phys_addr_t paddr = dma_addr & RAM_OFFSET_MASK;
>   
> diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
> index abc154d784b078..95b09313d2a4cf 100644
> --- a/arch/powerpc/include/asm/dma-direct.h
> +++ b/arch/powerpc/include/asm/dma-direct.h
> @@ -7,7 +7,7 @@ static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	return paddr + dev->archdata.dma_offset;
>   }
>   
> -static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
> +static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
>   {
>   	return daddr - dev->archdata.dma_offset;
>   }
> diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
> index 20eceb2e4f91f8..f00e262ab6b154 100644
> --- a/include/linux/dma-direct.h
> +++ b/include/linux/dma-direct.h
> @@ -24,11 +24,12 @@ static inline dma_addr_t __phys_to_dma(struct device *dev, phys_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)
> +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;
> +	phys_addr_t paddr = (phys_addr_t)dev_addr +
> +		((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
>   
> -	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
> +	return __sme_clr(paddr);
>   }
>   #endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
>   
> @@ -44,7 +45,7 @@ static inline bool force_dma_unencrypted(struct device *dev)
>   /*
>    * If memory encryption is supported, phys_to_dma will set the memory encryption
>    * bit in the DMA address, and dma_to_phys will clear it.  The raw __phys_to_dma
> - * and __dma_to_phys versions should only be used on non-encrypted memory for
> + * version should only be used on non-encrypted memory for
>    * special occasions like DMA coherent buffers.
>    */
>   static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
> @@ -52,11 +53,6 @@ static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
>   	return __sme_set(__phys_to_dma(dev, paddr));
>   }
>   
> -static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
> -{
> -	return __sme_clr(__dma_to_phys(dev, daddr));
> -}
> -
>   static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size,
>   		bool is_ram)
>   {
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index 57a6e7d7cf8f16..bfb479c8a370fa 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -48,11 +48,6 @@ static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
>   {
>   	u64 dma_limit = min_not_zero(dma_mask, dev->bus_dma_limit);
>   
> -	if (force_dma_unencrypted(dev))
> -		*phys_limit = __dma_to_phys(dev, dma_limit);
> -	else
> -		*phys_limit = dma_to_phys(dev, dma_limit);
> -
>   	/*
>   	 * Optimistically try the zone that the physical address mask falls
>   	 * into first.  If that returns memory that isn't actually addressable
> @@ -61,6 +56,7 @@ static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
>   	 * Note that GFP_DMA32 and GFP_DMA are no ops without the corresponding
>   	 * zones.
>   	 */
> +	*phys_limit = dma_to_phys(dev, dma_limit);
>   	if (*phys_limit <= DMA_BIT_MASK(zone_dma_bits))
>   		return GFP_DMA;
>   	if (*phys_limit <= DMA_BIT_MASK(32))
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 10/12] dma-direct: rename and cleanup __phys_to_dma
  2020-09-08 16:47 ` [PATCH 10/12] dma-direct: rename and cleanup __phys_to_dma Christoph Hellwig
@ 2020-09-10 13:30   ` Robin Murphy
  0 siblings, 0 replies; 27+ messages in thread
From: Robin Murphy @ 2020-09-10 13:30 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-mips, linux-kernel

On 2020-09-08 17:47, Christoph Hellwig wrote:
> The __phys_to_dma vs phys_to_dma distinction isn't exactly obvious.  Try
> to improve the situation by renaming __phys_to_dma to
> phys_to_dma_unencryped, and not forcing architectures that want to
> override phys_to_dma to actually provide __phys_to_dma.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   arch/arm/include/asm/dma-direct.h      |  2 +-
>   arch/mips/bmips/dma.c                  |  2 +-
>   arch/mips/cavium-octeon/dma-octeon.c   |  2 +-
>   arch/mips/include/asm/dma-direct.h     |  2 +-
>   arch/mips/loongson2ef/fuloong-2e/dma.c |  2 +-
>   arch/mips/loongson2ef/lemote-2f/dma.c  |  2 +-
>   arch/mips/loongson64/dma.c             |  2 +-
>   arch/mips/pci/pci-ar2315.c             |  2 +-
>   arch/mips/pci/pci-xtalk-bridge.c       |  2 +-
>   arch/mips/sgi-ip32/ip32-dma.c          |  2 +-
>   arch/powerpc/include/asm/dma-direct.h  |  2 +-
>   drivers/iommu/intel/iommu.c            |  2 +-
>   include/linux/dma-direct.h             | 28 +++++++++++++++-----------
>   kernel/dma/direct.c                    |  8 ++++----
>   kernel/dma/swiotlb.c                   |  4 ++--
>   15 files changed, 34 insertions(+), 30 deletions(-)
> 
> diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h
> index a8cee87a93e8ab..bca0de56753439 100644
> --- a/arch/arm/include/asm/dma-direct.h
> +++ b/arch/arm/include/asm/dma-direct.h
> @@ -2,7 +2,7 @@
>   #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)
> +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;
> diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c
> index ba2a5d33dfd3fa..49061b870680b9 100644
> --- a/arch/mips/bmips/dma.c
> +++ b/arch/mips/bmips/dma.c
> @@ -40,7 +40,7 @@ static struct bmips_dma_range *bmips_dma_ranges;
>   
>   #define FLUSH_RAC		0x100
>   
> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t pa)
> +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t pa)
>   {
>   	struct bmips_dma_range *r;
>   
> diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
> index 388b13ba2558c2..232fa1017b1ec9 100644
> --- a/arch/mips/cavium-octeon/dma-octeon.c
> +++ b/arch/mips/cavium-octeon/dma-octeon.c
> @@ -168,7 +168,7 @@ void __init octeon_pci_dma_init(void)
>   }
>   #endif /* CONFIG_PCI */
>   
> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
> +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
>   {
>   #ifdef CONFIG_PCI
>   	if (dev && dev_is_pci(dev))
> diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h
> index 8e178651c638c2..9a640118316c9d 100644
> --- a/arch/mips/include/asm/dma-direct.h
> +++ b/arch/mips/include/asm/dma-direct.h
> @@ -2,7 +2,7 @@
>   #ifndef _MIPS_DMA_DIRECT_H
>   #define _MIPS_DMA_DIRECT_H 1
>   
> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
> +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);
>   
>   #endif /* _MIPS_DMA_DIRECT_H */
> diff --git a/arch/mips/loongson2ef/fuloong-2e/dma.c b/arch/mips/loongson2ef/fuloong-2e/dma.c
> index 83fadeb3fd7d56..cea167d8aba8db 100644
> --- a/arch/mips/loongson2ef/fuloong-2e/dma.c
> +++ b/arch/mips/loongson2ef/fuloong-2e/dma.c
> @@ -1,7 +1,7 @@
>   // SPDX-License-Identifier: GPL-2.0
>   #include <linux/dma-direct.h>
>   
> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
> +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
>   {
>   	return paddr | 0x80000000;
>   }
> diff --git a/arch/mips/loongson2ef/lemote-2f/dma.c b/arch/mips/loongson2ef/lemote-2f/dma.c
> index 302b43a14eee74..3c9e994563578c 100644
> --- a/arch/mips/loongson2ef/lemote-2f/dma.c
> +++ b/arch/mips/loongson2ef/lemote-2f/dma.c
> @@ -1,7 +1,7 @@
>   // SPDX-License-Identifier: GPL-2.0
>   #include <linux/dma-direct.h>
>   
> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
> +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
>   {
>   	return paddr | 0x80000000;
>   }
> diff --git a/arch/mips/loongson64/dma.c b/arch/mips/loongson64/dma.c
> index b3dc5d0bd2b113..364f2f27c8723f 100644
> --- a/arch/mips/loongson64/dma.c
> +++ b/arch/mips/loongson64/dma.c
> @@ -4,7 +4,7 @@
>   #include <linux/swiotlb.h>
>   #include <boot_param.h>
>   
> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
> +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
>   {
>   	/* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
>   	 * Loongson-3's 48bit address space and embed it into 40bit */
> diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c
> index d88395684f487d..cef4a47ab06311 100644
> --- a/arch/mips/pci/pci-ar2315.c
> +++ b/arch/mips/pci/pci-ar2315.c
> @@ -170,7 +170,7 @@ static inline dma_addr_t ar2315_dev_offset(struct device *dev)
>   	return 0;
>   }
>   
> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
> +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
>   {
>   	return paddr + ar2315_dev_offset(dev);
>   }
> diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
> index f1b37f32b55395..50f7d42cca5a78 100644
> --- a/arch/mips/pci/pci-xtalk-bridge.c
> +++ b/arch/mips/pci/pci-xtalk-bridge.c
> @@ -25,7 +25,7 @@
>   /*
>    * Common phys<->dma mapping for platforms using pci xtalk bridge
>    */
> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
> +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
>   {
>   	struct pci_dev *pdev = to_pci_dev(dev);
>   	struct bridge_controller *bc = BRIDGE_CONTROLLER(pdev->bus);
> diff --git a/arch/mips/sgi-ip32/ip32-dma.c b/arch/mips/sgi-ip32/ip32-dma.c
> index 160317294d97a9..20c6da9d76bc5e 100644
> --- a/arch/mips/sgi-ip32/ip32-dma.c
> +++ b/arch/mips/sgi-ip32/ip32-dma.c
> @@ -18,7 +18,7 @@
>   
>   #define RAM_OFFSET_MASK 0x3fffffffUL
>   
> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
> +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
>   {
>   	dma_addr_t dma_addr = paddr & RAM_OFFSET_MASK;
>   
> diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
> index 95b09313d2a4cf..128304cbee1d87 100644
> --- a/arch/powerpc/include/asm/dma-direct.h
> +++ b/arch/powerpc/include/asm/dma-direct.h
> @@ -2,7 +2,7 @@
>   #ifndef ASM_POWERPC_DMA_DIRECT_H
>   #define ASM_POWERPC_DMA_DIRECT_H 1
>   
> -static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
> +static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
>   {
>   	return paddr + dev->archdata.dma_offset;
>   }
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index f8177c59d229a6..7983c13b9eef7d 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -3736,7 +3736,7 @@ bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size,
>   	 */
>   	if (!IS_ALIGNED(paddr | size, VTD_PAGE_SIZE)) {
>   		tlb_addr = swiotlb_tbl_map_single(dev,
> -				__phys_to_dma(dev, io_tlb_start),
> +				phys_to_dma_unencrypted(dev, io_tlb_start),
>   				paddr, size, aligned_size, dir, attrs);
>   		if (tlb_addr == DMA_MAPPING_ERROR) {
>   			goto swiotlb_error;
> diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
> index f00e262ab6b154..805010ea5346f9 100644
> --- a/include/linux/dma-direct.h
> +++ b/include/linux/dma-direct.h
> @@ -16,14 +16,29 @@ extern unsigned int zone_dma_bits;
>   
>   #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
>   #include <asm/dma-direct.h>
> +#ifndef phys_to_dma_unencrypted
> +#define phys_to_dma_unencrypted		phys_to_dma
> +#endif
>   #else
> -static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
> +static inline dma_addr_t phys_to_dma_unencrypted(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);
>   }
>   
> +/*
> + * If memory encryption is supported, phys_to_dma will set the memory encryption
> + * bit in the DMA address, and dma_to_phys will clear it.
> + * phys_to_dma_unencrypted is for use on special unencrypted memory like swiotlb
> + * buffers.
> + */
> +static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
> +{
> +	return __sme_set(phys_to_dma_unencrypted(dev, paddr));
> +}
> +
>   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 +
> @@ -42,17 +57,6 @@ static inline bool force_dma_unencrypted(struct device *dev)
>   }
>   #endif /* CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED */
>   
> -/*
> - * If memory encryption is supported, phys_to_dma will set the memory encryption
> - * bit in the DMA address, and dma_to_phys will clear it.  The raw __phys_to_dma
> - * version should only be used on non-encrypted memory for
> - * special occasions like DMA coherent buffers.
> - */
> -static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
> -{
> -	return __sme_set(__phys_to_dma(dev, paddr));
> -}
> -
>   static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size,
>   		bool is_ram)
>   {
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index bfb479c8a370fa..54db9cfdaecc6d 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -25,7 +25,7 @@ static inline dma_addr_t phys_to_dma_direct(struct device *dev,
>   		phys_addr_t phys)
>   {
>   	if (force_dma_unencrypted(dev))
> -		return __phys_to_dma(dev, phys);
> +		return phys_to_dma_unencrypted(dev, phys);
>   	return phys_to_dma(dev, phys);
>   }
>   
> @@ -438,13 +438,13 @@ int dma_direct_supported(struct device *dev, u64 mask)
>   		return 1;
>   
>   	/*
> -	 * This check needs to be against the actual bit mask value, so
> -	 * use __phys_to_dma() here so that the SME encryption mask isn't
> +	 * This check needs to be against the actual bit mask value, so use
> +	 * phys_to_dma_unencrypted() here so that the SME encryption mask isn't
>   	 * part of the check.
>   	 */
>   	if (IS_ENABLED(CONFIG_ZONE_DMA))
>   		min_mask = min_t(u64, min_mask, DMA_BIT_MASK(zone_dma_bits));
> -	return mask >= __phys_to_dma(dev, min_mask);
> +	return mask >= phys_to_dma_unencrypted(dev, min_mask);
>   }
>   
>   size_t dma_direct_max_mapping_size(struct device *dev)
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index c19379fabd200e..4ea72d145cd27d 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -670,13 +670,13 @@ dma_addr_t swiotlb_map(struct device *dev, phys_addr_t paddr, size_t size,
>   			      swiotlb_force);
>   
>   	swiotlb_addr = swiotlb_tbl_map_single(dev,
> -			__phys_to_dma(dev, io_tlb_start),
> +			phys_to_dma_unencrypted(dev, io_tlb_start),
>   			paddr, size, size, dir, attrs);
>   	if (swiotlb_addr == (phys_addr_t)DMA_MAPPING_ERROR)
>   		return DMA_MAPPING_ERROR;
>   
>   	/* Ensure that the address returned is DMA'ble */
> -	dma_addr = __phys_to_dma(dev, swiotlb_addr);
> +	dma_addr = phys_to_dma_unencrypted(dev, swiotlb_addr);
>   	if (unlikely(!dma_capable(dev, dma_addr, size, true))) {
>   		swiotlb_tbl_unmap_single(dev, swiotlb_addr, size, size, dir,
>   			attrs | DMA_ATTR_SKIP_CPU_SYNC);
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 11/12] dma-mapping: move dma_common_{mmap, get_sgtable} out of mapping.c
  2020-09-08 16:47 ` [PATCH 11/12] dma-mapping: move dma_common_{mmap, get_sgtable} out of mapping.c Christoph Hellwig
@ 2020-09-10 13:34   ` Robin Murphy
  2020-09-11  7:15     ` [PATCH 11/12] dma-mapping: move dma_common_{mmap,get_sgtable} " Christoph Hellwig
  0 siblings, 1 reply; 27+ messages in thread
From: Robin Murphy @ 2020-09-10 13:34 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-mips, linux-kernel

On 2020-09-08 17:47, Christoph Hellwig wrote:
> Add a new file that contains helpera for misc DMA ops, which is only

The Latin plural of the singular "helperum", I guess? :P

> built when CONFIG_DMA_OPS is set.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   kernel/dma/Makefile      |  1 +
>   kernel/dma/mapping.c     | 47 +-----------------------------------
>   kernel/dma/ops_helpers.c | 51 ++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 53 insertions(+), 46 deletions(-)
>   create mode 100644 kernel/dma/ops_helpers.c
> 
> diff --git a/kernel/dma/Makefile b/kernel/dma/Makefile
> index 32c7c1942bbd6c..dc755ab68aabf9 100644
> --- a/kernel/dma/Makefile
> +++ b/kernel/dma/Makefile
> @@ -1,6 +1,7 @@
>   # SPDX-License-Identifier: GPL-2.0
>   
>   obj-$(CONFIG_HAS_DMA)			+= mapping.o direct.o
> +obj-$(CONFIG_DMA_OPS)			+= ops_helpers.o
>   obj-$(CONFIG_DMA_OPS)			+= dummy.o
>   obj-$(CONFIG_DMA_CMA)			+= contiguous.o
>   obj-$(CONFIG_DMA_DECLARE_COHERENT)	+= coherent.o
> diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
> index 0d129421e75fc8..848c95c27d79ff 100644
> --- a/kernel/dma/mapping.c
> +++ b/kernel/dma/mapping.c
> @@ -8,7 +8,7 @@
>   #include <linux/memblock.h> /* for max_pfn */
>   #include <linux/acpi.h>
>   #include <linux/dma-direct.h>
> -#include <linux/dma-noncoherent.h>
> +#include <linux/dma-mapping.h>
>   #include <linux/export.h>
>   #include <linux/gfp.h>
>   #include <linux/of_device.h>
> @@ -295,22 +295,6 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>   }
>   EXPORT_SYMBOL(dma_sync_sg_for_device);
>   
> -/*
> - * Create scatter-list for the already allocated DMA buffer.
> - */
> -int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
> -		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		 unsigned long attrs)
> -{
> -	struct page *page = virt_to_page(cpu_addr);
> -	int ret;
> -
> -	ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
> -	if (!ret)
> -		sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
> -	return ret;
> -}
> -
>   /*
>    * The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
>    * that the intention is to allow exporting memory allocated via the
> @@ -358,35 +342,6 @@ pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs)
>   }
>   #endif /* CONFIG_MMU */
>   
> -/*
> - * Create userspace mapping for the DMA-coherent memory.
> - */
> -int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
> -		void *cpu_addr, dma_addr_t dma_addr, size_t size,
> -		unsigned long attrs)
> -{
> -#ifdef CONFIG_MMU
> -	unsigned long user_count = vma_pages(vma);
> -	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
> -	unsigned long off = vma->vm_pgoff;
> -	int ret = -ENXIO;
> -
> -	vma->vm_page_prot = dma_pgprot(dev, vma->vm_page_prot, attrs);
> -
> -	if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
> -		return ret;
> -
> -	if (off >= count || user_count > count - off)
> -		return -ENXIO;
> -
> -	return remap_pfn_range(vma, vma->vm_start,
> -			page_to_pfn(virt_to_page(cpu_addr)) + vma->vm_pgoff,
> -			user_count << PAGE_SHIFT, vma->vm_page_prot);
> -#else
> -	return -ENXIO;
> -#endif /* CONFIG_MMU */
> -}
> -
>   /**
>    * dma_can_mmap - check if a given device supports dma_mmap_*
>    * @dev: device to check
> diff --git a/kernel/dma/ops_helpers.c b/kernel/dma/ops_helpers.c
> new file mode 100644
> index 00000000000000..e443c69be4299f
> --- /dev/null
> +++ b/kernel/dma/ops_helpers.c
> @@ -0,0 +1,51 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Helpers for DMA ops implementations.  These generally rely on the fact that
> + * the allocated memory contains normal pages in the direct kernel mapping.
> + */
> +#include <linux/dma-noncoherent.h>
> +
> +/*
> + * Create scatter-list for the already allocated DMA buffer.
> + */
> +int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
> +		 void *cpu_addr, dma_addr_t dma_addr, size_t size,
> +		 unsigned long attrs)
> +{
> +	struct page *page = virt_to_page(cpu_addr);
> +	int ret;
> +
> +	ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
> +	if (!ret)
> +		sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
> +	return ret;
> +}
> +
> +/*
> + * Create userspace mapping for the DMA-coherent memory.
> + */
> +int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
> +		void *cpu_addr, dma_addr_t dma_addr, size_t size,
> +		unsigned long attrs)
> +{
> +#ifdef CONFIG_MMU
> +	unsigned long user_count = vma_pages(vma);
> +	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
> +	unsigned long off = vma->vm_pgoff;
> +	int ret = -ENXIO;
> +
> +	vma->vm_page_prot = dma_pgprot(dev, vma->vm_page_prot, attrs);
> +
> +	if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
> +		return ret;
> +
> +	if (off >= count || user_count > count - off)
> +		return -ENXIO;
> +
> +	return remap_pfn_range(vma, vma->vm_start,
> +			page_to_pfn(virt_to_page(cpu_addr)) + vma->vm_pgoff,
> +			user_count << PAGE_SHIFT, vma->vm_page_prot);
> +#else
> +	return -ENXIO;
> +#endif /* CONFIG_MMU */
> +}
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 12/12] dma-mapping: move the dma_declare_coherent_memory documentation
  2020-09-08 16:47 ` [PATCH 12/12] dma-mapping: move the dma_declare_coherent_memory documentation Christoph Hellwig
@ 2020-09-10 13:51   ` Robin Murphy
  2020-09-11  7:17     ` Christoph Hellwig
  0 siblings, 1 reply; 27+ messages in thread
From: Robin Murphy @ 2020-09-10 13:51 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Luck, Fenghua Yu, Thomas Bogendoerfer, iommu
  Cc: linux-ia64, linux-doc, linux-mips, linux-kernel

On 2020-09-08 17:47, Christoph Hellwig wrote:
> dma_declare_coherent_memory should not be in a DMA API guide aimed
> at driver writers (that is consumers of the API).  Move it to a comment
> near the function instead.

I still think there might be an occasional valid use for device-local 
memory outside the scope of platform code without the driver having to 
go full ZONE_DEVICE/HMM/TTM, e.g. with stuff like PCIe-based FPGA 
prototyping cards, but the kind of driver I'm imagining for that case 
would never be upstream anyway (if it were even written, rather than 
just using hard-coded hacks), so meh.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   Documentation/core-api/dma-api.rst | 24 ------------------------
>   kernel/dma/coherent.c              | 17 +++++++++++++++++
>   2 files changed, 17 insertions(+), 24 deletions(-)
> 
> diff --git a/Documentation/core-api/dma-api.rst b/Documentation/core-api/dma-api.rst
> index 3b3abbbb4b9a6f..90239348b30f6f 100644
> --- a/Documentation/core-api/dma-api.rst
> +++ b/Documentation/core-api/dma-api.rst
> @@ -586,30 +586,6 @@ the DMA_ATTR_NON_CONSISTENT flag starting at virtual address vaddr and
>   continuing on for size.  Again, you *must* observe the cache line
>   boundaries when doing this.
>   
> -::
> -
> -	int
> -	dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
> -				    dma_addr_t device_addr, size_t size);
> -
> -Declare region of memory to be handed out by dma_alloc_coherent() when
> -it's asked for coherent memory for this device.
> -
> -phys_addr is the CPU physical address to which the memory is currently
> -assigned (this will be ioremapped so the CPU can access the region).
> -
> -device_addr is the DMA address the device needs to be programmed
> -with to actually address this memory (this will be handed out as the
> -dma_addr_t in dma_alloc_coherent()).
> -
> -size is the size of the area (must be multiples of PAGE_SIZE).
> -
> -As a simplification for the platforms, only *one* such region of
> -memory may be declared per device.
> -
> -For reasons of efficiency, most platforms choose to track the declared
> -region only at the granularity of a page.  For smaller allocations,
> -you should use the dma_pool() API.
>   
>   Part III - Debug drivers use of the DMA-API
>   -------------------------------------------
> diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
> index 2a0c4985f38e41..f85d14bbfcbe03 100644
> --- a/kernel/dma/coherent.c
> +++ b/kernel/dma/coherent.c
> @@ -107,6 +107,23 @@ static int dma_assign_coherent_memory(struct device *dev,
>   	return 0;
>   }
>   
> +/*
> + * Declare a region of memory to be handed out by dma_alloc_coherent() when it
> + * is asked for coherent memory for this device.  This shall only be used
> + * from platform code, usually based on the device tree description.
> + *
> + * phys_addr is the CPU physical address to which the memory is currently
> + * assigned (this will be ioremapped so the CPU can access the region).
> + *
> + * device_addr is the DMA address the device needs to be programmed with to
> + * actually address this memory (this will be handed out as the dma_addr_t in
> + * dma_alloc_coherent()).
> + *
> + * size is the size of the area (must be a multiple of PAGE_SIZE).
> + *
> + * As a simplification for the platforms, only *one* such region of memory may
> + * be declared per device.
> + */
>   int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
>   				dma_addr_t device_addr, size_t size)
>   {
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies
  2020-09-10 12:55   ` Robin Murphy
@ 2020-09-11  7:09     ` Christoph Hellwig
  0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-11  7:09 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Fenghua Yu, Tony Luck, linux-ia64, linux-doc, linux-kernel,
	iommu, Thomas Bogendoerfer, linux-mips, Christoph Hellwig

On Thu, Sep 10, 2020 at 01:55:37PM +0100, Robin Murphy wrote:
> AFAICS all three of these bus drivers are only proxying a struct 
> dma_map_ops * pointer around, so if they used the set_dma_ops() helper they 
> shouldn't even need these selects at all. Only INTEL_MIC_HOST appears to 
> have a logical dependency on DMA_OPS for actual functionality.
>
> However, I have a vague feeling you might not be fond of those dma_ops 
> helpers, and I have no great objection to this one-liner as-is, so (modulo 
> the couple of commit message typos),

The problem with these inherіtances is that they don't actually work
for the general case.  You'd also need to inherity things like the
dma ranges, the bus limits, etc, etc.  So we need to kill them instead.
That whole mic/vop case is even worse than that with it's weird set
of chained dma ops that seems to implement some kind of device side
iommu that isn't in scope for the DMA API at all.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies
  2020-09-08 18:04   ` Sergei Shtylyov
@ 2020-09-11  7:10     ` Christoph Hellwig
  0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-11  7:10 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Fenghua Yu, Tony Luck, linux-ia64, linux-doc, linux-kernel,
	iommu, Thomas Bogendoerfer, linux-mips, Robin Murphy,
	Christoph Hellwig

On Tue, Sep 08, 2020 at 09:04:17PM +0300, Sergei Shtylyov wrote:
> Hello!
> 
> On 9/8/20 7:47 PM, Christoph Hellwig wrote:
> 
> > Driver that select DMA_OPS need to depend on HAS_DMA support to
> > work.  The vop driver was missing that dependency, so add it, and also
> > add a nother depends in DMA_OPS itself.  That won't fix the issue due
> 
>    Another? :-)

Yes, fixed.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 09/12] dma-direct: remove __dma_to_phys
  2020-09-10 13:26   ` Robin Murphy
@ 2020-09-11  7:14     ` Christoph Hellwig
  0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-11  7:14 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Fenghua Yu, Tony Luck, linux-ia64, linux-doc, linux-kernel,
	iommu, Thomas Bogendoerfer, linux-mips, Christoph Hellwig

On Thu, Sep 10, 2020 at 02:26:03PM +0100, Robin Murphy wrote:
> On 2020-09-08 17:47, Christoph Hellwig wrote:
>> There is no harm in just always clearing the SME encryption bit, while
>> significantly simplifying the interface.
>
> After a 10-minute diversion into "but hang on, force_dma_unencrypted() is 
> meaningful on PPC and S390 too..." before realising that it all does just 
> come back to __sme_clr(), which is indeed a no-op for everyone other than 
> AMD, any simplification of this mess is indeed welcome :)
>
> Unless I've massively misunderstood how SME is supposed to work,

Exactly.  This weird encryption bit in AMD SME causes all kinds of harm,
and I'm glad no one picked it up.  I've also been wondering if we
should change the interface to explicit set/clear the bit, but I'll
leave that for another pass as fixing up the SME interfaces would turn
into a massive disgression.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 11/12] dma-mapping: move dma_common_{mmap,get_sgtable} out of mapping.c
  2020-09-10 13:34   ` Robin Murphy
@ 2020-09-11  7:15     ` Christoph Hellwig
  0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-11  7:15 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Fenghua Yu, Tony Luck, linux-ia64, linux-doc, linux-kernel,
	iommu, Thomas Bogendoerfer, linux-mips, Christoph Hellwig

On Thu, Sep 10, 2020 at 02:34:18PM +0100, Robin Murphy wrote:
> On 2020-09-08 17:47, Christoph Hellwig wrote:
>> Add a new file that contains helpera for misc DMA ops, which is only
>
> The Latin plural of the singular "helperum", I guess? :P

I've switched it to helpers, that might be easier to understand :)
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 12/12] dma-mapping: move the dma_declare_coherent_memory documentation
  2020-09-10 13:51   ` Robin Murphy
@ 2020-09-11  7:17     ` Christoph Hellwig
  0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2020-09-11  7:17 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Fenghua Yu, Tony Luck, linux-ia64, linux-doc, linux-kernel,
	iommu, Thomas Bogendoerfer, linux-mips, Christoph Hellwig

On Thu, Sep 10, 2020 at 02:51:47PM +0100, Robin Murphy wrote:
> On 2020-09-08 17:47, Christoph Hellwig wrote:
>> dma_declare_coherent_memory should not be in a DMA API guide aimed
>> at driver writers (that is consumers of the API).  Move it to a comment
>> near the function instead.
>
> I still think there might be an occasional valid use for device-local 
> memory outside the scope of platform code without the driver having to go 
> full ZONE_DEVICE/HMM/TTM, e.g. with stuff like PCIe-based FPGA prototyping 
> cards, but the kind of driver I'm imagining for that case would never be 
> upstream anyway (if it were even written, rather than just using hard-coded 
> hacks), so meh.

And I'm not sure this would be the right interface for it.  E.g. NVMe
has the concept of a Controller Memory buffer (and a similar persistent
variant not supported by Linux), where the device can do this local DMA
(in a completely broken way that relies on correlating addresses seen
by the device and those by the host, but that's another disgression).
But that memory obviously can also be addresses by other devices using
PCIe P2P transactions which would also be useful for any HMM-ish devices,
so we'd need to expose it as P2P memory anyay..
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2020-09-11  7:17 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
2020-09-08 16:47 ` [PATCH 01/12] MIPS: make dma_sync_*_for_cpu a little less overzealous Christoph Hellwig
2020-09-08 16:47 ` [PATCH 02/12] MIPS/jazzdma: remove the unused vdma_remap function Christoph Hellwig
2020-09-08 16:47 ` [PATCH 03/12] MIPS/jazzdma: decouple from dma-direct Christoph Hellwig
2020-09-08 16:47 ` [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies Christoph Hellwig
2020-09-08 18:04   ` Sergei Shtylyov
2020-09-11  7:10     ` Christoph Hellwig
2020-09-10 12:55   ` Robin Murphy
2020-09-11  7:09     ` Christoph Hellwig
2020-09-08 16:47 ` [PATCH 05/12] dma-mapping: add (back) arch_dma_mark_clean for ia64 Christoph Hellwig
2020-09-08 16:47 ` [PATCH 06/12] dma-direct: remove dma_direct_{alloc,free}_pages Christoph Hellwig
2020-09-10 12:57   ` Robin Murphy
2020-09-08 16:47 ` [PATCH 07/12] dma-direct: lift gfp_t manipulation out of__dma_direct_alloc_pages Christoph Hellwig
2020-09-10 13:02   ` Robin Murphy
2020-09-08 16:47 ` [PATCH 08/12] dma-direct: use phys_to_dma_direct in dma_direct_alloc Christoph Hellwig
2020-09-10 13:03   ` Robin Murphy
2020-09-08 16:47 ` [PATCH 09/12] dma-direct: remove __dma_to_phys Christoph Hellwig
2020-09-10 13:26   ` Robin Murphy
2020-09-11  7:14     ` Christoph Hellwig
2020-09-08 16:47 ` [PATCH 10/12] dma-direct: rename and cleanup __phys_to_dma Christoph Hellwig
2020-09-10 13:30   ` Robin Murphy
2020-09-08 16:47 ` [PATCH 11/12] dma-mapping: move dma_common_{mmap, get_sgtable} out of mapping.c Christoph Hellwig
2020-09-10 13:34   ` Robin Murphy
2020-09-11  7:15     ` [PATCH 11/12] dma-mapping: move dma_common_{mmap,get_sgtable} " Christoph Hellwig
2020-09-08 16:47 ` [PATCH 12/12] dma-mapping: move the dma_declare_coherent_memory documentation Christoph Hellwig
2020-09-10 13:51   ` Robin Murphy
2020-09-11  7:17     ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).