linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* remove default fallbacks in dma_map_ops v3
@ 2019-08-08 15:59 Christoph Hellwig
  2019-08-08 15:59 ` [PATCH 1/8] dma-mapping: provide a better default ->get_required_mask Christoph Hellwig
                   ` (8 more replies)
  0 siblings, 9 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-08 15:59 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

Hi all,

we have a few places where the DMA mapping layer has non-trivial default
actions that are questionable and/or dangerous.

This series instead wires up the mmap, get_sgtable and get_required_mask
methods explicitly and cleans up some surrounding areas.  This also means
we could get rid of the ARCH_NO_COHERENT_DMA_MMAP kconfig option, as we
now require a mmap method wired up, or in case of non-coherent dma-direct
the presence of the arch_dma_coherent_to_pfn hook.  The only interesting
case is that the sound code also checked the ARCH_NO_COHERENT_DMA_MMAP
symbol in somewhat odd ways, so I'd like to see a review of the sound
situation before going forward with that patch.

Changes since v2:
 - fix use of dma_can_mmap in alsa
 - improve the CONFIG_* mess a little more

Changes since v1:
 - add a dma_can_mmap helper for alsa

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

* [PATCH 1/8] dma-mapping: provide a better default ->get_required_mask
  2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
@ 2019-08-08 15:59 ` Christoph Hellwig
  2019-08-08 15:59 ` [PATCH 2/8] dma-mapping: move the dma_get_sgtable API comments from arm to common code Christoph Hellwig
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-08 15:59 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

Most dma_map_ops instances are IOMMUs that work perfectly fine in 32-bits
of IOVA space, and the generic direct mapping code already provides its
own routines that is intelligent based on the amount of memory actually
present.  Wire up the dma-direct routine for the ARM direct mapping code
as well, and otherwise default to the constant 32-bit mask.  This way
we only need to override it for the occasional odd IOMMU that requires
64-bit IOVA support, or IOMMU drivers that are more efficient if they
can fall back to the direct mapping.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm/mm/dma-mapping.c               |  3 +++
 arch/powerpc/platforms/ps3/system-bus.c |  7 ------
 arch/x86/kernel/amd_gart_64.c           |  1 +
 kernel/dma/mapping.c                    | 30 +++++++++----------------
 4 files changed, 14 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 8c0b0baeb398..ad64d32fb39a 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/dma-direct.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-noncoherent.h>
 #include <linux/dma-contiguous.h>
@@ -192,6 +193,7 @@ const struct dma_map_ops arm_dma_ops = {
 	.sync_sg_for_cpu	= arm_dma_sync_sg_for_cpu,
 	.sync_sg_for_device	= arm_dma_sync_sg_for_device,
 	.dma_supported		= arm_dma_supported,
+	.get_required_mask	= dma_direct_get_required_mask,
 };
 EXPORT_SYMBOL(arm_dma_ops);
 
@@ -212,6 +214,7 @@ const struct dma_map_ops arm_coherent_dma_ops = {
 	.map_sg			= arm_dma_map_sg,
 	.map_resource		= dma_direct_map_resource,
 	.dma_supported		= arm_dma_supported,
+	.get_required_mask	= dma_direct_get_required_mask,
 };
 EXPORT_SYMBOL(arm_coherent_dma_ops);
 
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 98410119c47b..6818317073b9 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -686,18 +686,12 @@ static int ps3_dma_supported(struct device *_dev, u64 mask)
 	return mask >= DMA_BIT_MASK(32);
 }
 
-static u64 ps3_dma_get_required_mask(struct device *_dev)
-{
-	return DMA_BIT_MASK(32);
-}
-
 static const struct dma_map_ops ps3_sb_dma_ops = {
 	.alloc = ps3_alloc_coherent,
 	.free = ps3_free_coherent,
 	.map_sg = ps3_sb_map_sg,
 	.unmap_sg = ps3_sb_unmap_sg,
 	.dma_supported = ps3_dma_supported,
-	.get_required_mask = ps3_dma_get_required_mask,
 	.map_page = ps3_sb_map_page,
 	.unmap_page = ps3_unmap_page,
 };
@@ -708,7 +702,6 @@ static const struct dma_map_ops ps3_ioc0_dma_ops = {
 	.map_sg = ps3_ioc0_map_sg,
 	.unmap_sg = ps3_ioc0_unmap_sg,
 	.dma_supported = ps3_dma_supported,
-	.get_required_mask = ps3_dma_get_required_mask,
 	.map_page = ps3_ioc0_map_page,
 	.unmap_page = ps3_unmap_page,
 };
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index a585ea6f686a..03ed9675f954 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -678,6 +678,7 @@ static const struct dma_map_ops gart_dma_ops = {
 	.alloc				= gart_alloc_coherent,
 	.free				= gart_free_coherent,
 	.dma_supported			= dma_direct_supported,
+	.get_required_mask		= dma_direct_get_required_mask,
 };
 
 static void gart_iommu_shutdown(void)
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index b0038ca3aa92..9c0f6a8eb5cb 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -233,25 +233,6 @@ int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 }
 EXPORT_SYMBOL(dma_mmap_attrs);
 
-static u64 dma_default_get_required_mask(struct device *dev)
-{
-	u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT);
-	u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT));
-	u64 mask;
-
-	if (!high_totalram) {
-		/* convert to mask just covering totalram */
-		low_totalram = (1 << (fls(low_totalram) - 1));
-		low_totalram += low_totalram - 1;
-		mask = low_totalram;
-	} else {
-		high_totalram = (1 << (fls(high_totalram) - 1));
-		high_totalram += high_totalram - 1;
-		mask = (((u64)high_totalram) << 32) + 0xffffffff;
-	}
-	return mask;
-}
-
 u64 dma_get_required_mask(struct device *dev)
 {
 	const struct dma_map_ops *ops = get_dma_ops(dev);
@@ -260,7 +241,16 @@ u64 dma_get_required_mask(struct device *dev)
 		return dma_direct_get_required_mask(dev);
 	if (ops->get_required_mask)
 		return ops->get_required_mask(dev);
-	return dma_default_get_required_mask(dev);
+
+	/*
+	 * We require every DMA ops implementation to at least support a 32-bit
+	 * DMA mask (and use bounce buffering if that isn't supported in
+	 * hardware).  As the direct mapping code has its own routine to
+	 * actually report an optimal mask we default to 32-bit here as that
+	 * is the right thing for most IOMMUs, and at least not actively
+	 * harmful in general.
+	 */
+	return DMA_BIT_MASK(32);
 }
 EXPORT_SYMBOL_GPL(dma_get_required_mask);
 
-- 
2.20.1


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

* [PATCH 2/8] dma-mapping: move the dma_get_sgtable API comments from arm to common code
  2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
  2019-08-08 15:59 ` [PATCH 1/8] dma-mapping: provide a better default ->get_required_mask Christoph Hellwig
@ 2019-08-08 15:59 ` Christoph Hellwig
  2019-08-08 16:00 ` [PATCH 3/8] dma-mapping: explicitly wire up ->mmap and ->get_sgtable Christoph Hellwig
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-08 15:59 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

The comments are spot on and should be near the central API, not just
near a single implementation.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm/mm/dma-mapping.c | 11 -----------
 kernel/dma/mapping.c      | 11 +++++++++++
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ad64d32fb39a..b4d65da76393 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -880,17 +880,6 @@ static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_add
 	__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
 }
 
-/*
- * The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
- * that the intention is to allow exporting memory allocated via the
- * coherent DMA APIs through the dma_buf API, which only accepts a
- * scattertable.  This presents a couple of problems:
- * 1. Not all memory allocated via the coherent DMA APIs is backed by
- *    a struct page
- * 2. Passing coherent DMA memory into the streaming APIs is not allowed
- *    as we will try to flush the memory through a different alias to that
- *    actually being used (and the flushes are redundant.)
- */
 int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
 		 void *cpu_addr, dma_addr_t handle, size_t size,
 		 unsigned long attrs)
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 9c0f6a8eb5cb..41590d003465 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -136,6 +136,17 @@ int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
 	return ret;
 }
 
+/*
+ * The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
+ * that the intention is to allow exporting memory allocated via the
+ * coherent DMA APIs through the dma_buf API, which only accepts a
+ * scattertable.  This presents a couple of problems:
+ * 1. Not all memory allocated via the coherent DMA APIs is backed by
+ *    a struct page
+ * 2. Passing coherent DMA memory into the streaming APIs is not allowed
+ *    as we will try to flush the memory through a different alias to that
+ *    actually being used (and the flushes are redundant.)
+ */
 int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt,
 		void *cpu_addr, dma_addr_t dma_addr, size_t size,
 		unsigned long attrs)
-- 
2.20.1


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

* [PATCH 3/8] dma-mapping: explicitly wire up ->mmap and ->get_sgtable
  2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
  2019-08-08 15:59 ` [PATCH 1/8] dma-mapping: provide a better default ->get_required_mask Christoph Hellwig
  2019-08-08 15:59 ` [PATCH 2/8] dma-mapping: move the dma_get_sgtable API comments from arm to common code Christoph Hellwig
@ 2019-08-08 16:00 ` Christoph Hellwig
  2019-08-08 16:00 ` [PATCH 4/8] dma-mapping: add a dma_can_mmap helper Christoph Hellwig
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-08 16:00 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

While the default ->mmap and ->get_sgtable implementations work for the
majority of our dma_map_ops impementations they are inherently safe
for others that don't use the page allocator or CMA and/or use their
own way of remapping not covered by the common code.  So remove the
defaults if these methods are not wired up, but instead wire up the
default implementations for all safe instances.

Fixes: e1c7e324539a ("dma-mapping: always provide the dma_map_ops based implementation")
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/alpha/kernel/pci_iommu.c           |  2 ++
 arch/ia64/hp/common/sba_iommu.c         |  2 ++
 arch/ia64/sn/pci/pci_dma.c              |  2 ++
 arch/mips/jazz/jazzdma.c                |  2 ++
 arch/powerpc/kernel/dma-iommu.c         |  2 ++
 arch/powerpc/platforms/ps3/system-bus.c |  4 ++++
 arch/powerpc/platforms/pseries/vio.c    |  2 ++
 arch/s390/pci/pci_dma.c                 |  2 ++
 arch/x86/kernel/amd_gart_64.c           |  2 ++
 arch/x86/kernel/pci-calgary_64.c        |  2 ++
 drivers/iommu/amd_iommu.c               |  2 ++
 drivers/iommu/intel-iommu.c             |  2 ++
 drivers/parisc/ccio-dma.c               |  2 ++
 drivers/parisc/sba_iommu.c              |  2 ++
 kernel/dma/mapping.c                    | 20 ++++++++++++--------
 15 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 242108439f42..7f1925a32c99 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -955,5 +955,7 @@ const struct dma_map_ops alpha_pci_ops = {
 	.map_sg			= alpha_pci_map_sg,
 	.unmap_sg		= alpha_pci_unmap_sg,
 	.dma_supported		= alpha_pci_supported,
+	.mmap			= dma_common_mmap,
+	.get_sgtable		= dma_common_get_sgtable,
 };
 EXPORT_SYMBOL(alpha_pci_ops);
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 3d24cc43385b..4c0ea6c2833d 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -2183,6 +2183,8 @@ const struct dma_map_ops sba_dma_ops = {
 	.map_sg			= sba_map_sg_attrs,
 	.unmap_sg		= sba_unmap_sg_attrs,
 	.dma_supported		= sba_dma_supported,
+	.mmap			= dma_common_mmap,
+	.get_sgtable		= dma_common_get_sgtable,
 };
 
 void sba_dma_init(void)
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index b7d42e4edc1f..12ffb9c0d738 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -438,6 +438,8 @@ static struct dma_map_ops sn_dma_ops = {
 	.unmap_sg		= sn_dma_unmap_sg,
 	.dma_supported		= sn_dma_supported,
 	.get_required_mask	= sn_dma_get_required_mask,
+	.mmap			= dma_common_mmap,
+	.get_sgtable		= dma_common_get_sgtable,
 };
 
 void sn_dma_init(void)
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
index 1804dc9d8136..a01e14955187 100644
--- a/arch/mips/jazz/jazzdma.c
+++ b/arch/mips/jazz/jazzdma.c
@@ -682,5 +682,7 @@ const struct dma_map_ops jazz_dma_ops = {
 	.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,
 };
 EXPORT_SYMBOL(jazz_dma_ops);
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index a0879674a9c8..2f5a53874f6d 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -208,4 +208,6 @@ const struct dma_map_ops dma_iommu_ops = {
 	.sync_single_for_device	= dma_iommu_sync_for_device,
 	.sync_sg_for_cpu	= dma_iommu_sync_sg_for_cpu,
 	.sync_sg_for_device	= dma_iommu_sync_sg_for_device,
+	.mmap			= dma_common_mmap,
+	.get_sgtable		= dma_common_get_sgtable,
 };
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 6818317073b9..3542b7bd6a46 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -694,6 +694,8 @@ static const struct dma_map_ops ps3_sb_dma_ops = {
 	.dma_supported = ps3_dma_supported,
 	.map_page = ps3_sb_map_page,
 	.unmap_page = ps3_unmap_page,
+	.mmap = dma_common_mmap,
+	.get_sgtable = dma_common_get_sgtable,
 };
 
 static const struct dma_map_ops ps3_ioc0_dma_ops = {
@@ -704,6 +706,8 @@ static const struct dma_map_ops ps3_ioc0_dma_ops = {
 	.dma_supported = ps3_dma_supported,
 	.map_page = ps3_ioc0_map_page,
 	.unmap_page = ps3_unmap_page,
+	.mmap = dma_common_mmap,
+	.get_sgtable = dma_common_get_sgtable,
 };
 
 /**
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index 6601b9d404dc..3473eef7628c 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -605,6 +605,8 @@ static const struct dma_map_ops vio_dma_mapping_ops = {
 	.unmap_page        = vio_dma_iommu_unmap_page,
 	.dma_supported     = dma_iommu_dma_supported,
 	.get_required_mask = dma_iommu_get_required_mask,
+	.mmap		   = dma_common_mmap,
+	.get_sgtable	   = dma_common_get_sgtable,
 };
 
 /**
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index 9e52d1527f71..03d8c1c9f82f 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -668,6 +668,8 @@ const struct dma_map_ops s390_pci_dma_ops = {
 	.unmap_sg	= s390_dma_unmap_sg,
 	.map_page	= s390_dma_map_pages,
 	.unmap_page	= s390_dma_unmap_pages,
+	.mmap		= dma_common_mmap,
+	.get_sgtable	= dma_common_get_sgtable,
 	/* dma_supported is unconditionally true without a callback */
 };
 EXPORT_SYMBOL_GPL(s390_pci_dma_ops);
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index 03ed9675f954..a6ac3712db8b 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -677,6 +677,8 @@ static const struct dma_map_ops gart_dma_ops = {
 	.unmap_page			= gart_unmap_page,
 	.alloc				= gart_alloc_coherent,
 	.free				= gart_free_coherent,
+	.mmap				= dma_common_mmap,
+	.get_sgtable			= dma_common_get_sgtable,
 	.dma_supported			= dma_direct_supported,
 	.get_required_mask		= dma_direct_get_required_mask,
 };
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 9d4343aa481b..23fdec030c37 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -468,6 +468,8 @@ static const struct dma_map_ops calgary_dma_ops = {
 	.map_page = calgary_map_page,
 	.unmap_page = calgary_unmap_page,
 	.dma_supported = dma_direct_supported,
+	.mmap = dma_common_mmap,
+	.get_sgtable = dma_common_get_sgtable,
 };
 
 static inline void __iomem * busno_to_bbar(unsigned char num)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index b607a92791d3..2e74ad659985 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2722,6 +2722,8 @@ static const struct dma_map_ops amd_iommu_dma_ops = {
 	.map_sg		= map_sg,
 	.unmap_sg	= unmap_sg,
 	.dma_supported	= amd_iommu_dma_supported,
+	.mmap		= dma_common_mmap,
+	.get_sgtable	= dma_common_get_sgtable,
 };
 
 static int init_reserved_iova_ranges(void)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index bdaed2da8a55..7505c5d9cf78 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3737,6 +3737,8 @@ static const struct dma_map_ops intel_dma_ops = {
 	.map_resource = intel_map_resource,
 	.unmap_resource = intel_unmap_resource,
 	.dma_supported = dma_direct_supported,
+	.mmap = dma_common_mmap,
+	.get_sgtable = dma_common_get_sgtable,
 };
 
 static inline int iommu_domain_cache_init(void)
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 217f15aafa4a..1d7125d29bee 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1024,6 +1024,8 @@ static const struct dma_map_ops ccio_ops = {
 	.unmap_page =		ccio_unmap_page,
 	.map_sg = 		ccio_map_sg,
 	.unmap_sg = 		ccio_unmap_sg,
+	.mmap =			dma_common_mmap,
+	.get_sgtable =		dma_common_get_sgtable,
 };
 
 #ifdef CONFIG_PROC_FS
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 296668caf7e5..fa4df65b7e28 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1084,6 +1084,8 @@ static const struct dma_map_ops sba_ops = {
 	.unmap_page =		sba_unmap_page,
 	.map_sg =		sba_map_sg,
 	.unmap_sg =		sba_unmap_sg,
+	.mmap =			dma_common_mmap,
+	.get_sgtable =		dma_common_get_sgtable,
 };
 
 
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 41590d003465..67b900ad0836 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -153,11 +153,12 @@ int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt,
 {
 	const struct dma_map_ops *ops = get_dma_ops(dev);
 
-	if (!dma_is_direct(ops) && ops->get_sgtable)
-		return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
-					attrs);
-	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
-			attrs);
+	if (dma_is_direct(ops))
+		return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr,
+				size, attrs);
+	if (!ops->get_sgtable)
+		return -ENXIO;
+	return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size, attrs);
 }
 EXPORT_SYMBOL(dma_get_sgtable_attrs);
 
@@ -238,9 +239,12 @@ int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 {
 	const struct dma_map_ops *ops = get_dma_ops(dev);
 
-	if (!dma_is_direct(ops) && ops->mmap)
-		return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
-	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
+	if (dma_is_direct(ops))
+		return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size,
+				attrs);
+	if (!ops->mmap)
+		return -ENXIO;
+	return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
 }
 EXPORT_SYMBOL(dma_mmap_attrs);
 
-- 
2.20.1


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

* [PATCH 4/8] dma-mapping: add a dma_can_mmap helper
  2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2019-08-08 16:00 ` [PATCH 3/8] dma-mapping: explicitly wire up ->mmap and ->get_sgtable Christoph Hellwig
@ 2019-08-08 16:00 ` Christoph Hellwig
  2019-08-08 16:00 ` [PATCH 5/8] ALSA: pcm: use dma_can_mmap() to check if a device supports dma_mmap_* Christoph Hellwig
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-08 16:00 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

Add a helper to check if DMA allocations for a specific device can be
mapped to userspace using dma_mmap_*.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/dma-mapping.h |  5 +++++
 kernel/dma/mapping.c        | 23 +++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f7d1eea32c78..17271857be5d 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -462,6 +462,7 @@ int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt,
 int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 		void *cpu_addr, dma_addr_t dma_addr, size_t size,
 		unsigned long attrs);
+bool dma_can_mmap(struct device *dev);
 int dma_supported(struct device *dev, u64 mask);
 int dma_set_mask(struct device *dev, u64 mask);
 int dma_set_coherent_mask(struct device *dev, u64 mask);
@@ -552,6 +553,10 @@ static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 {
 	return -ENXIO;
 }
+static inline bool dma_can_mmap(struct device *dev)
+{
+	return false;
+}
 static inline int dma_supported(struct device *dev, u64 mask)
 {
 	return 0;
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 67b900ad0836..64d1de59e133 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -220,6 +220,29 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
 #endif /* !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */
 }
 
+/**
+ * dma_can_mmap - check if a given device supports dma_mmap_*
+ * @dev: device to check
+ *
+ * Returns %true if @dev supports dma_mmap_coherent() and dma_mmap_attrs() to
+ * map DMA allocations to userspace.
+ */
+bool dma_can_mmap(struct device *dev)
+{
+	const struct dma_map_ops *ops = get_dma_ops(dev);
+
+	if (IS_ENABLED(CONFIG_ARCH_NO_COHERENT_DMA_MMAP))
+		return false;
+
+	if (dma_is_direct(ops)) {
+		return dev_is_dma_coherent(dev) ||
+			IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN);
+	}
+
+	return ops->mmap != NULL;
+}
+EXPORT_SYMBOL_GPL(dma_can_mmap);
+
 /**
  * dma_mmap_attrs - map a coherent DMA allocation into user space
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
-- 
2.20.1


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

* [PATCH 5/8] ALSA: pcm: use dma_can_mmap() to check if a device supports dma_mmap_*
  2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2019-08-08 16:00 ` [PATCH 4/8] dma-mapping: add a dma_can_mmap helper Christoph Hellwig
@ 2019-08-08 16:00 ` Christoph Hellwig
  2019-11-04  7:26   ` youling257
  2019-08-08 16:00 ` [PATCH 6/8] arm-nommu: call dma_mmap_from_dev_coherent directly Christoph Hellwig
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-08 16:00 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

Replace the local hack with the dma_can_mmap helper to check if
a given device supports mapping DMA allocations to userspace.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/pcm_native.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 703857aab00f..9763c18e176a 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -220,13 +220,12 @@ static bool hw_support_mmap(struct snd_pcm_substream *substream)
 {
 	if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP))
 		return false;
-	/* architecture supports dma_mmap_coherent()? */
-#if defined(CONFIG_ARCH_NO_COHERENT_DMA_MMAP) || !defined(CONFIG_HAS_DMA)
-	if (!substream->ops->mmap &&
-	    substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
-		return false;
-#endif
-	return true;
+
+	if (substream->ops->mmap ||
+	    substream->dma_buffer.dev.type != SNDRV_DMA_TYPE_DEV)
+		return true;
+
+	return dma_can_mmap(substream->dma_buffer.dev.dev);
 }
 
 static int constrain_mask_params(struct snd_pcm_substream *substream,
-- 
2.20.1


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

* [PATCH 6/8] arm-nommu: call dma_mmap_from_dev_coherent directly
  2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2019-08-08 16:00 ` [PATCH 5/8] ALSA: pcm: use dma_can_mmap() to check if a device supports dma_mmap_* Christoph Hellwig
@ 2019-08-08 16:00 ` Christoph Hellwig
  2019-08-09  9:35   ` Sergei Shtylyov
  2019-08-08 16:00 ` [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP Christoph Hellwig
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-08 16:00 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

Ther is no need to go through dma_common_mmap for the arm-nommu
dma mmap implementation as the only possible memory not handled above
could be that from the per-device coherent pool.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm/mm/dma-mapping-nommu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index 52b82559d99b..db9247898300 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -68,8 +68,9 @@ static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 
 	if (dma_mmap_from_global_coherent(vma, cpu_addr, size, &ret))
 		return ret;
-
-	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
+	if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
+		return ret;
+	return -ENXIO;
 }
 
 
-- 
2.20.1


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

* [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP
  2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2019-08-08 16:00 ` [PATCH 6/8] arm-nommu: call dma_mmap_from_dev_coherent directly Christoph Hellwig
@ 2019-08-08 16:00 ` Christoph Hellwig
  2019-08-15  7:36   ` Christoph Hellwig
  2019-08-15  9:25   ` James Bottomley
  2019-08-08 16:00 ` [PATCH 8/8] dma-mapping: remove CONFIG_ARCH_NO_COHERENT_DMA_MMAP Christoph Hellwig
  2019-08-29 15:38 ` remove default fallbacks in dma_map_ops v3 Christoph Hellwig
  8 siblings, 2 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-08 16:00 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

parisc is the only architecture that sets ARCH_NO_COHERENT_DMA_MMAP
when an MMU is enabled.  AFAIK this is because parisc CPUs use VIVT
caches, which means exporting normally cachable memory to userspace is
relatively dangrous due to cache aliasing.

But normally cachable memory is only allocated by dma_alloc_coherent
on parisc when using the sba_iommu or ccio_iommu drivers, so just
remove the .mmap implementation for them so that we don't have to set
ARCH_NO_COHERENT_DMA_MMAP, which I plan to get rid of.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/parisc/Kconfig        | 1 -
 drivers/parisc/ccio-dma.c  | 1 -
 drivers/parisc/sba_iommu.c | 1 -
 3 files changed, 3 deletions(-)

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 6d732e451071..e9dd88b7f81e 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -52,7 +52,6 @@ config PARISC
 	select GENERIC_SCHED_CLOCK
 	select HAVE_UNSTABLE_SCHED_CLOCK if SMP
 	select GENERIC_CLOCKEVENTS
-	select ARCH_NO_COHERENT_DMA_MMAP
 	select CPU_NO_EFFICIENT_FFS
 	select NEED_DMA_MAP_STATE
 	select NEED_SG_DMA_LENGTH
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 1d7125d29bee..ad290f79983b 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1024,7 +1024,6 @@ static const struct dma_map_ops ccio_ops = {
 	.unmap_page =		ccio_unmap_page,
 	.map_sg = 		ccio_map_sg,
 	.unmap_sg = 		ccio_unmap_sg,
-	.mmap =			dma_common_mmap,
 	.get_sgtable =		dma_common_get_sgtable,
 };
 
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index fa4df65b7e28..ed50502cc65a 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1084,7 +1084,6 @@ static const struct dma_map_ops sba_ops = {
 	.unmap_page =		sba_unmap_page,
 	.map_sg =		sba_map_sg,
 	.unmap_sg =		sba_unmap_sg,
-	.mmap =			dma_common_mmap,
 	.get_sgtable =		dma_common_get_sgtable,
 };
 
-- 
2.20.1


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

* [PATCH 8/8] dma-mapping: remove CONFIG_ARCH_NO_COHERENT_DMA_MMAP
  2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
                   ` (6 preceding siblings ...)
  2019-08-08 16:00 ` [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP Christoph Hellwig
@ 2019-08-08 16:00 ` Christoph Hellwig
  2019-08-09  7:21   ` Geert Uytterhoeven
  2019-08-29 15:38 ` remove default fallbacks in dma_map_ops v3 Christoph Hellwig
  8 siblings, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-08 16:00 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

CONFIG_ARCH_NO_COHERENT_DMA_MMAP is now functionally identical to
!CONFIG_MMU, so remove the separate symbol.  The only difference is that
arm did not set it for !CONFIG_MMU, but arm uses a separate dma mapping
implementation including its own mmap method, which is handled by moving
the CONFIG_MMU check in dma_can_mmap so that is only applies to the
dma-direct case, just as the other ifdefs for it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/Kconfig            |  3 ---
 arch/c6x/Kconfig        |  1 -
 arch/m68k/Kconfig       |  1 -
 arch/microblaze/Kconfig |  1 -
 arch/sh/Kconfig         |  1 -
 arch/xtensa/Kconfig     |  1 -
 kernel/dma/mapping.c    | 12 +++++-------
 7 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index a7b57dd42c26..ec2834206d08 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -790,9 +790,6 @@ config COMPAT_32BIT_TIME
 	  This is relevant on all 32-bit architectures, and 64-bit architectures
 	  as part of compat syscall handling.
 
-config ARCH_NO_COHERENT_DMA_MMAP
-	bool
-
 config ARCH_NO_PREEMPT
 	bool
 
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index b4fb61c83494..e65e8d82442a 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -20,7 +20,6 @@ config C6X
 	select OF_EARLY_FLATTREE
 	select GENERIC_CLOCKEVENTS
 	select MODULES_USE_ELF_RELA
-	select ARCH_NO_COHERENT_DMA_MMAP
 	select MMU_GATHER_NO_RANGE if MMU
 
 config MMU
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index c518d695c376..614b355ae338 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -8,7 +8,6 @@ config M68K
 	select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
 	select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
 	select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
-	select ARCH_NO_COHERENT_DMA_MMAP if !MMU
 	select ARCH_NO_PREEMPT if !COLDFIRE
 	select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
 	select DMA_DIRECT_REMAP if HAS_DMA && MMU && !COLDFIRE
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index d411de05b628..632c9477a0f6 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -9,7 +9,6 @@ config MICROBLAZE
 	select ARCH_HAS_SYNC_DMA_FOR_CPU
 	select ARCH_HAS_SYNC_DMA_FOR_DEVICE
 	select ARCH_MIGHT_HAVE_PC_PARPORT
-	select ARCH_NO_COHERENT_DMA_MMAP if !MMU
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select BUILDTIME_EXTABLE_SORT
 	select TIMER_OF
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 6b1b5941b618..f356ee674d89 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -5,7 +5,6 @@ config SUPERH
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_MIGHT_HAVE_PC_PARPORT
-	select ARCH_NO_COHERENT_DMA_MMAP if !MMU
 	select HAVE_PATA_PLATFORM
 	select CLKDEV_LOOKUP
 	select DMA_DECLARE_COHERENT
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index ebc135bda921..70653aed3005 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -5,7 +5,6 @@ config XTENSA
 	select ARCH_HAS_BINFMT_FLAT if !MMU
 	select ARCH_HAS_SYNC_DMA_FOR_CPU
 	select ARCH_HAS_SYNC_DMA_FOR_DEVICE
-	select ARCH_NO_COHERENT_DMA_MMAP if !MMU
 	select ARCH_USE_QUEUED_RWLOCKS
 	select ARCH_USE_QUEUED_SPINLOCKS
 	select ARCH_WANT_FRAME_POINTERS
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 64d1de59e133..fc17016b0871 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -186,7 +186,7 @@ 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)
 {
-#ifndef CONFIG_ARCH_NO_COHERENT_DMA_MMAP
+#ifdef CONFIG_MMU
 	unsigned long user_count = vma_pages(vma);
 	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 	unsigned long off = vma->vm_pgoff;
@@ -217,7 +217,7 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
 			user_count << PAGE_SHIFT, vma->vm_page_prot);
 #else
 	return -ENXIO;
-#endif /* !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */
+#endif /* CONFIG_MMU */
 }
 
 /**
@@ -231,12 +231,10 @@ bool dma_can_mmap(struct device *dev)
 {
 	const struct dma_map_ops *ops = get_dma_ops(dev);
 
-	if (IS_ENABLED(CONFIG_ARCH_NO_COHERENT_DMA_MMAP))
-		return false;
-
 	if (dma_is_direct(ops)) {
-		return dev_is_dma_coherent(dev) ||
-			IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN);
+		return IS_ENABLED(CONFIG_MMU) &&
+		       (dev_is_dma_coherent(dev) ||
+			IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN));
 	}
 
 	return ops->mmap != NULL;
-- 
2.20.1


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

* Re: [PATCH 8/8] dma-mapping: remove CONFIG_ARCH_NO_COHERENT_DMA_MMAP
  2019-08-08 16:00 ` [PATCH 8/8] dma-mapping: remove CONFIG_ARCH_NO_COHERENT_DMA_MMAP Christoph Hellwig
@ 2019-08-09  7:21   ` Geert Uytterhoeven
  0 siblings, 0 replies; 17+ messages in thread
From: Geert Uytterhoeven @ 2019-08-09  7:21 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Linux IOMMU, Marek Szyprowski, Vladimir Murzin, Takashi Iwai,
	Helge Deller, Robin Murphy, Michal Simek, Linux ARM, linux-m68k,
	Parisc List, Linux-sh list, linux-xtensa, linuxppc-dev,
	the arch/x86 maintainers, Linux Kernel Mailing List

Hi Christoph,

On Thu, Aug 8, 2019 at 6:01 PM Christoph Hellwig <hch@lst.de> wrote:
> CONFIG_ARCH_NO_COHERENT_DMA_MMAP is now functionally identical to
> !CONFIG_MMU, so remove the separate symbol.  The only difference is that
> arm did not set it for !CONFIG_MMU, but arm uses a separate dma mapping
> implementation including its own mmap method, which is handled by moving
> the CONFIG_MMU check in dma_can_mmap so that is only applies to the
> dma-direct case, just as the other ifdefs for it.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

>  arch/m68k/Kconfig       |  1 -

For m68k:
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

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

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

* Re: [PATCH 6/8] arm-nommu: call dma_mmap_from_dev_coherent directly
  2019-08-08 16:00 ` [PATCH 6/8] arm-nommu: call dma_mmap_from_dev_coherent directly Christoph Hellwig
@ 2019-08-09  9:35   ` Sergei Shtylyov
  0 siblings, 0 replies; 17+ messages in thread
From: Sergei Shtylyov @ 2019-08-09  9:35 UTC (permalink / raw)
  To: Christoph Hellwig, iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

On 08.08.2019 19:00, Christoph Hellwig wrote:

> Ther is no need to go through dma_common_mmap for the arm-nommu

    There. :-)

> dma mmap implementation as the only possible memory not handled above
> could be that from the per-device coherent pool.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
[...]

MBR, Sergei

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

* Re: [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP
  2019-08-08 16:00 ` [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP Christoph Hellwig
@ 2019-08-15  7:36   ` Christoph Hellwig
  2019-08-15  9:25   ` James Bottomley
  1 sibling, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-15  7:36 UTC (permalink / raw)
  To: Helge Deller
  Cc: x86, iommu, Marek Szyprowski, linux-xtensa, Michal Simek,
	Vladimir Murzin, linux-parisc, linux-sh, Takashi Iwai,
	linuxppc-dev, linux-kernel, linux-m68k, Robin Murphy,
	linux-arm-kernel

Helger, or other parisc folks: can you take a look at this patch
in particular and the series in general?  Thanks!

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

* Re: [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP
  2019-08-08 16:00 ` [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP Christoph Hellwig
  2019-08-15  7:36   ` Christoph Hellwig
@ 2019-08-15  9:25   ` James Bottomley
  2019-08-15 10:50     ` Christoph Hellwig
  1 sibling, 1 reply; 17+ messages in thread
From: James Bottomley @ 2019-08-15  9:25 UTC (permalink / raw)
  To: Christoph Hellwig, iommu, Marek Szyprowski
  Cc: Vladimir Murzin, Takashi Iwai, Helge Deller, Robin Murphy,
	Michal Simek, linux-arm-kernel, linux-m68k, linux-parisc,
	linux-sh, linux-xtensa, linuxppc-dev, x86, linux-kernel

On Thu, 2019-08-08 at 19:00 +0300, Christoph Hellwig wrote:
> parisc is the only architecture that sets ARCH_NO_COHERENT_DMA_MMAP
> when an MMU is enabled.  AFAIK this is because parisc CPUs use VIVT
> caches,

We're actually VIPT but the same principle applies.

>  which means exporting normally cachable memory to userspace is
> relatively dangrous due to cache aliasing.
> 
> But normally cachable memory is only allocated by dma_alloc_coherent
> on parisc when using the sba_iommu or ccio_iommu drivers, so just
> remove the .mmap implementation for them so that we don't have to set
> ARCH_NO_COHERENT_DMA_MMAP, which I plan to get rid of.

So I don't think this is quite right.  We have three architectural
variants essentially (hidden behind about 12 cpu types):

   1. pa70xx: These can't turn off page caching, so they were the non
      coherent problem case
   2. pa71xx: These can manufacture coherent memory simply by turning off
      the cache on a per page basis
   3. pa8xxx: these have a full cache flush coherence mechanism.

(I might have this slightly wrong: I vaguely remember the pa71xxlc
variants have some weird cache quirks for DMA as well)

So I think pa70xx we can't mmap.  pa71xx we can provided we mark the
page as uncached ... which should already have happened in the allocate
and pa8xxx which can always mmap dma memory without any special tricks.

James


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

* Re: [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP
  2019-08-15  9:25   ` James Bottomley
@ 2019-08-15 10:50     ` Christoph Hellwig
  2019-08-19 14:25       ` Christoph Hellwig
  0 siblings, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-15 10:50 UTC (permalink / raw)
  To: James Bottomley
  Cc: Christoph Hellwig, iommu, Marek Szyprowski, Vladimir Murzin,
	Takashi Iwai, Helge Deller, Robin Murphy, Michal Simek,
	linux-arm-kernel, linux-m68k, linux-parisc, linux-sh,
	linux-xtensa, linuxppc-dev, x86, linux-kernel

On Thu, Aug 15, 2019 at 10:25:52AM +0100, James Bottomley wrote:
> >  which means exporting normally cachable memory to userspace is
> > relatively dangrous due to cache aliasing.
> > 
> > But normally cachable memory is only allocated by dma_alloc_coherent
> > on parisc when using the sba_iommu or ccio_iommu drivers, so just
> > remove the .mmap implementation for them so that we don't have to set
> > ARCH_NO_COHERENT_DMA_MMAP, which I plan to get rid of.
> 
> So I don't think this is quite right.  We have three architectural
> variants essentially (hidden behind about 12 cpu types):
> 
>    1. pa70xx: These can't turn off page caching, so they were the non
>       coherent problem case
>    2. pa71xx: These can manufacture coherent memory simply by turning off
>       the cache on a per page basis
>    3. pa8xxx: these have a full cache flush coherence mechanism.
> 
> (I might have this slightly wrong: I vaguely remember the pa71xxlc
> variants have some weird cache quirks for DMA as well)
> 
> So I think pa70xx we can't mmap.  pa71xx we can provided we mark the
> page as uncached ... which should already have happened in the allocate
> and pa8xxx which can always mmap dma memory without any special tricks.

Except for the different naming scheme vs the code this matches my
assumptions.

In the code we have three cases (and a fourth EISA case mention in
comments, but not actually implemented as far as I can tell):

arch/parisc/kernel/pci-dma.c says in the top of file comments:

** AFAIK, all PA7100LC and PA7300LC platforms can use this code.

and the handles two different case.  for cpu_type == pcxl or pcxl2
it maps the memory as uncached for dma_alloc_coherent, and for all
other cpu types it fails the coherent allocations.

In addition to that there are the ccio and sba iommu drivers, of which
according to your above comment one is always present for pa8xxx.

Which brings us back to this patch, which ensures that no cacheable
memory is exported to userspace by removing ->mmap from ccio and sba.
It then enabled dma_mmap_coherent for the pcxl or pcxl2 case that
allocates uncached memory, which dma_mmap_coherent does not work
because dma_alloc_coherent already failed for the !pcxl && !pcxl2
and thus there is no memory to mmap.

So if the description is too confusing please suggest a better
one, I'm a little lost between all these code names and product
names (arch/parisc/include/asm/dma-mapping.h uses yet another set).

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

* Re: [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP
  2019-08-15 10:50     ` Christoph Hellwig
@ 2019-08-19 14:25       ` Christoph Hellwig
  0 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-19 14:25 UTC (permalink / raw)
  To: James Bottomley
  Cc: Christoph Hellwig, iommu, Marek Szyprowski, Vladimir Murzin,
	Takashi Iwai, Helge Deller, Robin Murphy, Michal Simek,
	linux-arm-kernel, linux-m68k, linux-parisc, linux-sh,
	linux-xtensa, linuxppc-dev, x86, linux-kernel

Does my explanation from Thursday make sense or is it completely
off?  Does the patch description need some update to be less
confusing to those used to different terminology?

On Thu, Aug 15, 2019 at 12:50:02PM +0200, Christoph Hellwig wrote:
> Except for the different naming scheme vs the code this matches my
> assumptions.
> 
> In the code we have three cases (and a fourth EISA case mention in
> comments, but not actually implemented as far as I can tell):
> 
> arch/parisc/kernel/pci-dma.c says in the top of file comments:
> 
> ** AFAIK, all PA7100LC and PA7300LC platforms can use this code.
> 
> and the handles two different case.  for cpu_type == pcxl or pcxl2
> it maps the memory as uncached for dma_alloc_coherent, and for all
> other cpu types it fails the coherent allocations.
> 
> In addition to that there are the ccio and sba iommu drivers, of which
> according to your above comment one is always present for pa8xxx.
> 
> Which brings us back to this patch, which ensures that no cacheable
> memory is exported to userspace by removing ->mmap from ccio and sba.
> It then enabled dma_mmap_coherent for the pcxl or pcxl2 case that
> allocates uncached memory, which dma_mmap_coherent does not work
> because dma_alloc_coherent already failed for the !pcxl && !pcxl2
> and thus there is no memory to mmap.
> 
> So if the description is too confusing please suggest a better
> one, I'm a little lost between all these code names and product
> names (arch/parisc/include/asm/dma-mapping.h uses yet another set).
---end quoted text---

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

* Re: remove default fallbacks in dma_map_ops v3
  2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
                   ` (7 preceding siblings ...)
  2019-08-08 16:00 ` [PATCH 8/8] dma-mapping: remove CONFIG_ARCH_NO_COHERENT_DMA_MMAP Christoph Hellwig
@ 2019-08-29 15:38 ` Christoph Hellwig
  8 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2019-08-29 15:38 UTC (permalink / raw)
  To: iommu, Marek Szyprowski
  Cc: linux-xtensa, Michal Simek, Vladimir Murzin, linux-parisc,
	linux-sh, Takashi Iwai, linuxppc-dev, Helge Deller, x86,
	linux-kernel, linux-m68k, Robin Murphy, linux-arm-kernel

I've applied this to the dma-mapping for-next tree now.

If there are any issues with the parisc patch I'll happily take
incremental patches.

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

* Re: ALSA: pcm: use dma_can_mmap() to check if a device supports dma_mmap_*
  2019-08-08 16:00 ` [PATCH 5/8] ALSA: pcm: use dma_can_mmap() to check if a device supports dma_mmap_* Christoph Hellwig
@ 2019-11-04  7:26   ` youling257
  0 siblings, 0 replies; 17+ messages in thread
From: youling257 @ 2019-11-04  7:26 UTC (permalink / raw)
  To: hch
  Cc: linux-xtensa, monstr, vladimir.murzin, linux-parisc, linux-sh,
	tiwai, linuxppc-dev, deller, x86, linux-kernel, gregkh

This patch cause oops on android mainline kernel about gadget audio_source.

Androidx86 run on android mainline kernel.


[ 385.104963] android_work: sent uevent USB_STATE=CONNECTED

[ 385.109006] android_work: sent uevent USB_STATE=DISCONNECTED

[ 385.182024] android_work: sent uevent USB_STATE=CONNECTED

[ 385.184737] configfs-gadget gadget: high-speed config #1: b

[ 385.184921] android_work: sent uevent USB_STATE=CONFIGURED

[ 385.285268] BUG: kernel NULL pointer dereference, address: 
0000000000000220

[ 385.285339] #PF: supervisor read access in kernel mode

[ 385.285374] #PF: error_code(0x0000) - not-present page

[ 385.285436] PGD 80000000791e6067 P4D 80000000791e6067 PUD 0

[ 385.285473] Oops: 0000 [#1] PREEMPT SMP PTI

[ 385.285509] CPU: 0 PID: 5780 Comm: Binder:1383_5 Tainted: G O

5.4.0-rc6-android-x86_64+ #1

[ 385.285571] Hardware name: Insyde ONDA Tablet/ONDA Tablet, BIOS

ONDA.D890HBBNR0A 03/11/2015

[ 385.285639] RIP: 0010:dma_can_mmap+0x5/0x30

[ 385.285675] Code: 74 11 e9 ae 98 b2 00 48 8b 05 9f 40 94 01 48 85 c0

75 e3 31 c0 c3 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 0f 1f 44

00 00 <48> 8b 87 20 02 00 00 48 85 c0 74 09 48 83 78 10 00 0f 95 c0 c3

48

[ 385.285762] RSP: 0018:ffffb39443b63b78 EFLAGS: 00010246

[ 385.285797] RAX: 0000000000000001 RBX: ffffa28b91756600 RCX: 
0000000000000040

[ 385.285857] RDX: ffffffffb62b2a00 RSI: 0000000000000000 RDI: 
0000000000000000

[ 385.285917] RBP: ffffa28bac69f800 R08: ffffffffb63141b0 R09: 
ffffa28bf9a34a88

[ 385.285952] R10: ffffffffb62b2be0 R11: ffffffffb62b2bd0 R12: 
0000000000000008

[ 385.286013] R13: 0000000000000000 R14: ffffa28bacd736a8 R15: 
ffffa28bacd736c8

[ 385.286076] FS: 0000000000000000(0000) GS:ffffa28bfb600000(0063)

knlGS:00000000f5d81970

[ 385.286110] CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033

[ 385.286171] CR2: 0000000000000220 CR3: 000000007b2f6000 CR4: 
00000000001006f0

[ 385.286232] Call Trace:

[ 385.286275] snd_pcm_hw_constraints_complete+0x3e/0x1f0

[ 385.286314] snd_pcm_open_substream+0x94/0x140

[ 385.286377] snd_pcm_open+0xf0/0x240

[ 385.286416] ? wake_up_q+0x60/0x60

[ 385.286460] snd_pcm_playback_open+0x3d/0x60

[ 385.286533] chrdev_open+0xa2/0x1c0

[ 385.286574] ? cdev_put.part.0+0x20/0x20

[ 385.286615] do_dentry_open+0x13a/0x380

[ 385.286686] path_openat+0x588/0x15d0

[ 385.286728] do_filp_open+0x91/0x100

[ 385.286769] ? __check_object_size+0x136/0x147

[ 385.286840] do_sys_open+0x184/0x280

[ 385.286880] ? handle_mm_fault+0xd7/0x1c0

[ 385.286920] do_fast_syscall_32+0x8e/0x250

[ 385.286992] entry_SYSENTER_compat+0x7c/0x8e


[ 385.287302] CR2: 0000000000000220

[ 385.287391] ---[ end trace 73ffcefcbbe2b9a0 ]---

[ 385.296269] RIP: 0010:dma_can_mmap+0x5/0x30

[ 385.296337] Code: 74 11 e9 ae 98 b2 00 48 8b 05 9f 40 94 01 48 85 c0

75 e3 31 c0 c3 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 0f 1f 44

00 00 <48> 8b 87 20 02 00 00 48 85 c0 74 09 48 83 78 10 00 0f 95 c0 c3

48

[ 385.296407] RSP: 0018:ffffb39443b63b78 EFLAGS: 00010246

[ 385.296477] RAX: 0000000000000001 RBX: ffffa28b91756600 RCX: 
0000000000000040

[ 385.296516] RDX: ffffffffb62b2a00 RSI: 0000000000000000 RDI: 
0000000000000000

[ 385.296584] RBP: ffffa28bac69f800 R08: ffffffffb63141b0 R09: 
ffffa28bf9a34a88

[ 385.296654] R10: ffffffffb62b2be0 R11: ffffffffb62b2bd0 R12: 
0000000000000008

[ 385.296693] R13: 0000000000000000 R14: ffffa28bacd736a8 R15: 
ffffa28bacd736c8

[ 385.296761] FS: 0000000000000000(0000) GS:ffffa28bfb600000(0063)

knlGS:00000000f5d81970

[ 385.296830] CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033

[ 385.296867] CR2: 0000000000000220 CR3: 000000007b2f6000 CR4: 
00000000001006f0

[ 385.296936] Kernel panic - not syncing: Fatal exception

[ 385.296985] Kernel Offset: 0x33e00000 from 0xffffffff81000000

(relocation range: 0xffffffff80000000-0xffffffffbfffffff)

[ 385.305185] Rebooting in 5 seconds..


Revert it no the oops.



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

end of thread, other threads:[~2019-11-04  7:27 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-08 15:59 remove default fallbacks in dma_map_ops v3 Christoph Hellwig
2019-08-08 15:59 ` [PATCH 1/8] dma-mapping: provide a better default ->get_required_mask Christoph Hellwig
2019-08-08 15:59 ` [PATCH 2/8] dma-mapping: move the dma_get_sgtable API comments from arm to common code Christoph Hellwig
2019-08-08 16:00 ` [PATCH 3/8] dma-mapping: explicitly wire up ->mmap and ->get_sgtable Christoph Hellwig
2019-08-08 16:00 ` [PATCH 4/8] dma-mapping: add a dma_can_mmap helper Christoph Hellwig
2019-08-08 16:00 ` [PATCH 5/8] ALSA: pcm: use dma_can_mmap() to check if a device supports dma_mmap_* Christoph Hellwig
2019-11-04  7:26   ` youling257
2019-08-08 16:00 ` [PATCH 6/8] arm-nommu: call dma_mmap_from_dev_coherent directly Christoph Hellwig
2019-08-09  9:35   ` Sergei Shtylyov
2019-08-08 16:00 ` [PATCH 7/8] parisc: don't set ARCH_NO_COHERENT_DMA_MMAP Christoph Hellwig
2019-08-15  7:36   ` Christoph Hellwig
2019-08-15  9:25   ` James Bottomley
2019-08-15 10:50     ` Christoph Hellwig
2019-08-19 14:25       ` Christoph Hellwig
2019-08-08 16:00 ` [PATCH 8/8] dma-mapping: remove CONFIG_ARCH_NO_COHERENT_DMA_MMAP Christoph Hellwig
2019-08-09  7:21   ` Geert Uytterhoeven
2019-08-29 15:38 ` remove default fallbacks in dma_map_ops v3 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).