linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* unify the dma_capable definition
@ 2019-11-13  7:35 Christoph Hellwig
  2019-11-13  7:35 ` [PATCH 1/3] dma-direct: unify the dma_capable definitions Christoph Hellwig
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Christoph Hellwig @ 2019-11-13  7:35 UTC (permalink / raw)
  To: Nicolas Saenz Julienne, iommu, Russell King
  Cc: linux-arm-kernel, linux-mips, linuxppc-dev

Hi all,

there is no good reason to have different version of dma_capable.
This series removes the arch overrides and also adds a few cleanups
in the same area.

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

* [PATCH 1/3] dma-direct: unify the dma_capable definitions
  2019-11-13  7:35 unify the dma_capable definition Christoph Hellwig
@ 2019-11-13  7:35 ` Christoph Hellwig
  2019-11-14  8:47   ` Michael Ellerman
  2019-11-19  9:27   ` Marek Szyprowski
  2019-11-13  7:35 ` [PATCH 2/3] dma-direct: avoid a forward declaration for phys_to_dma Christoph Hellwig
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 14+ messages in thread
From: Christoph Hellwig @ 2019-11-13  7:35 UTC (permalink / raw)
  To: Nicolas Saenz Julienne, iommu, Russell King
  Cc: linux-arm-kernel, linux-mips, linuxppc-dev

Currently each architectures that wants to override dma_to_phys and
phys_to_dma also has to provide dma_capable.  But there isn't really
any good reason for that.  powerpc and mips just have copies of the
generic one minus the latests fix, and the arm one was the inspiration
for said fix, but misses the bus_dma_mask handling.
Make all architectures use the generic version instead.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm/include/asm/dma-direct.h     | 19 -------------------
 arch/mips/include/asm/dma-direct.h    |  8 --------
 arch/powerpc/include/asm/dma-direct.h |  9 ---------
 include/linux/dma-direct.h            |  2 +-
 4 files changed, 1 insertion(+), 37 deletions(-)

diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h
index b67e5fc1fe43..7c3001a6a775 100644
--- a/arch/arm/include/asm/dma-direct.h
+++ b/arch/arm/include/asm/dma-direct.h
@@ -14,23 +14,4 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
 	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
 }
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	u64 limit, mask;
-
-	if (!dev->dma_mask)
-		return 0;
-
-	mask = *dev->dma_mask;
-
-	limit = (mask + 1) & ~mask;
-	if (limit && size > limit)
-		return 0;
-
-	if ((addr | (addr + size - 1)) & ~mask)
-		return 0;
-
-	return 1;
-}
-
 #endif /* ASM_ARM_DMA_DIRECT_H */
diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h
index b5c240806e1b..14e352651ce9 100644
--- a/arch/mips/include/asm/dma-direct.h
+++ b/arch/mips/include/asm/dma-direct.h
@@ -2,14 +2,6 @@
 #ifndef _MIPS_DMA_DIRECT_H
 #define _MIPS_DMA_DIRECT_H 1
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
 dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
 phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr);
 
diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
index a2912b47102c..e29e8a236b8d 100644
--- a/arch/powerpc/include/asm/dma-direct.h
+++ b/arch/powerpc/include/asm/dma-direct.h
@@ -2,15 +2,6 @@
 #ifndef ASM_POWERPC_DMA_DIRECT_H
 #define ASM_POWERPC_DMA_DIRECT_H 1
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <=
-		min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
-}
-
 static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 	if (!dev)
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index 6db863c3eb93..991f8aa2676e 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -24,6 +24,7 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
 
 	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
 }
+#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
 
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
@@ -38,7 +39,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 
 	return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
 }
-#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
 
 #ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED
 bool force_dma_unencrypted(struct device *dev);
-- 
2.20.1


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

* [PATCH 2/3] dma-direct: avoid a forward declaration for phys_to_dma
  2019-11-13  7:35 unify the dma_capable definition Christoph Hellwig
  2019-11-13  7:35 ` [PATCH 1/3] dma-direct: unify the dma_capable definitions Christoph Hellwig
@ 2019-11-13  7:35 ` Christoph Hellwig
  2019-11-13  7:35 ` [PATCH 3/3] powerpc: remove support for NULL dev in __phys_to_dma / __dma_to_phys Christoph Hellwig
  2019-11-13 10:18 ` unify the dma_capable definition Nicolas Saenz Julienne
  3 siblings, 0 replies; 14+ messages in thread
From: Christoph Hellwig @ 2019-11-13  7:35 UTC (permalink / raw)
  To: Nicolas Saenz Julienne, iommu, Russell King
  Cc: linux-arm-kernel, linux-mips, linuxppc-dev

Move dma_capable down a bit so that we don't need a forward declaration
for phys_to_dma.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/dma-direct.h | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index 991f8aa2676e..f8959f75e496 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -6,8 +6,6 @@
 #include <linux/memblock.h> /* for min_low_pfn */
 #include <linux/mem_encrypt.h>
 
-static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
-
 #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
 #include <asm/dma-direct.h>
 #else
@@ -26,20 +24,6 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
 }
 #endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
 
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	dma_addr_t end = addr + size - 1;
-
-	if (!dev->dma_mask)
-		return false;
-
-	if (!IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) &&
-	    min(addr, end) < phys_to_dma(dev, PFN_PHYS(min_low_pfn)))
-		return false;
-
-	return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
-}
-
 #ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED
 bool force_dma_unencrypted(struct device *dev);
 #else
@@ -65,6 +49,20 @@ 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)
+{
+	dma_addr_t end = addr + size - 1;
+
+	if (!dev->dma_mask)
+		return false;
+
+	if (!IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) &&
+	    min(addr, end) < phys_to_dma(dev, PFN_PHYS(min_low_pfn)))
+		return false;
+
+	return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
+}
+
 u64 dma_direct_get_required_mask(struct device *dev);
 void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		gfp_t gfp, unsigned long attrs);
-- 
2.20.1


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

* [PATCH 3/3] powerpc: remove support for NULL dev in __phys_to_dma / __dma_to_phys
  2019-11-13  7:35 unify the dma_capable definition Christoph Hellwig
  2019-11-13  7:35 ` [PATCH 1/3] dma-direct: unify the dma_capable definitions Christoph Hellwig
  2019-11-13  7:35 ` [PATCH 2/3] dma-direct: avoid a forward declaration for phys_to_dma Christoph Hellwig
@ 2019-11-13  7:35 ` Christoph Hellwig
  2019-11-14  8:48   ` Michael Ellerman
  2019-11-13 10:18 ` unify the dma_capable definition Nicolas Saenz Julienne
  3 siblings, 1 reply; 14+ messages in thread
From: Christoph Hellwig @ 2019-11-13  7:35 UTC (permalink / raw)
  To: Nicolas Saenz Julienne, iommu, Russell King
  Cc: linux-arm-kernel, linux-mips, linuxppc-dev

Support for calling the DMA API functions without a valid device pointer
was removed a while ago, so remove the stale support for that from the
powerpc __phys_to_dma / __dma_to_phys helpers.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/powerpc/include/asm/dma-direct.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
index e29e8a236b8d..abc154d784b0 100644
--- a/arch/powerpc/include/asm/dma-direct.h
+++ b/arch/powerpc/include/asm/dma-direct.h
@@ -4,15 +4,11 @@
 
 static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
-	if (!dev)
-		return paddr + PCI_DRAM_OFFSET;
 	return paddr + dev->archdata.dma_offset;
 }
 
 static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
 {
-	if (!dev)
-		return daddr - PCI_DRAM_OFFSET;
 	return daddr - dev->archdata.dma_offset;
 }
 #endif /* ASM_POWERPC_DMA_DIRECT_H */
-- 
2.20.1


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

* Re: unify the dma_capable definition
  2019-11-13  7:35 unify the dma_capable definition Christoph Hellwig
                   ` (2 preceding siblings ...)
  2019-11-13  7:35 ` [PATCH 3/3] powerpc: remove support for NULL dev in __phys_to_dma / __dma_to_phys Christoph Hellwig
@ 2019-11-13 10:18 ` Nicolas Saenz Julienne
  3 siblings, 0 replies; 14+ messages in thread
From: Nicolas Saenz Julienne @ 2019-11-13 10:18 UTC (permalink / raw)
  To: Christoph Hellwig, iommu, Russell King
  Cc: linuxppc-dev, linux-mips, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 337 bytes --]

On Wed, 2019-11-13 at 08:35 +0100, Christoph Hellwig wrote:
> Hi all,
> 
> there is no good reason to have different version of dma_capable.
> This series removes the arch overrides and also adds a few cleanups
> in the same area.

Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>

for the whole series,
Thanks!


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
  2019-11-13  7:35 ` [PATCH 1/3] dma-direct: unify the dma_capable definitions Christoph Hellwig
@ 2019-11-14  8:47   ` Michael Ellerman
  2019-11-19  9:27   ` Marek Szyprowski
  1 sibling, 0 replies; 14+ messages in thread
From: Michael Ellerman @ 2019-11-14  8:47 UTC (permalink / raw)
  To: Christoph Hellwig, Nicolas Saenz Julienne, iommu, Russell King
  Cc: linuxppc-dev, linux-mips, linux-arm-kernel

Christoph Hellwig <hch@lst.de> writes:
> Currently each architectures that wants to override dma_to_phys and
> phys_to_dma also has to provide dma_capable.  But there isn't really
> any good reason for that.  powerpc and mips just have copies of the
> generic one minus the latests fix, and the arm one was the inspiration
> for said fix, but misses the bus_dma_mask handling.
> Make all architectures use the generic version instead.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/arm/include/asm/dma-direct.h     | 19 -------------------
>  arch/mips/include/asm/dma-direct.h    |  8 --------
>  arch/powerpc/include/asm/dma-direct.h |  9 ---------

Looks OK to me.

Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)

cheers

> diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h
> index b67e5fc1fe43..7c3001a6a775 100644
> --- a/arch/arm/include/asm/dma-direct.h
> +++ b/arch/arm/include/asm/dma-direct.h
> @@ -14,23 +14,4 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
>  	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
>  }
>  
> -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
> -{
> -	u64 limit, mask;
> -
> -	if (!dev->dma_mask)
> -		return 0;
> -
> -	mask = *dev->dma_mask;
> -
> -	limit = (mask + 1) & ~mask;
> -	if (limit && size > limit)
> -		return 0;
> -
> -	if ((addr | (addr + size - 1)) & ~mask)
> -		return 0;
> -
> -	return 1;
> -}
> -
>  #endif /* ASM_ARM_DMA_DIRECT_H */
> diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h
> index b5c240806e1b..14e352651ce9 100644
> --- a/arch/mips/include/asm/dma-direct.h
> +++ b/arch/mips/include/asm/dma-direct.h
> @@ -2,14 +2,6 @@
>  #ifndef _MIPS_DMA_DIRECT_H
>  #define _MIPS_DMA_DIRECT_H 1
>  
> -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
> -{
> -	if (!dev->dma_mask)
> -		return false;
> -
> -	return addr + size - 1 <= *dev->dma_mask;
> -}
> -
>  dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
>  phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr);
>  
> diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
> index a2912b47102c..e29e8a236b8d 100644
> --- a/arch/powerpc/include/asm/dma-direct.h
> +++ b/arch/powerpc/include/asm/dma-direct.h
> @@ -2,15 +2,6 @@
>  #ifndef ASM_POWERPC_DMA_DIRECT_H
>  #define ASM_POWERPC_DMA_DIRECT_H 1
>  
> -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
> -{
> -	if (!dev->dma_mask)
> -		return false;
> -
> -	return addr + size - 1 <=
> -		min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
> -}
> -
>  static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>  {
>  	if (!dev)
> diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
> index 6db863c3eb93..991f8aa2676e 100644
> --- a/include/linux/dma-direct.h
> +++ b/include/linux/dma-direct.h
> @@ -24,6 +24,7 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
>  
>  	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
>  }
> +#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
>  
>  static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
>  {
> @@ -38,7 +39,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
>  
>  	return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
>  }
> -#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
>  
>  #ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED
>  bool force_dma_unencrypted(struct device *dev);
> -- 
> 2.20.1

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

* Re: [PATCH 3/3] powerpc: remove support for NULL dev in __phys_to_dma / __dma_to_phys
  2019-11-13  7:35 ` [PATCH 3/3] powerpc: remove support for NULL dev in __phys_to_dma / __dma_to_phys Christoph Hellwig
@ 2019-11-14  8:48   ` Michael Ellerman
  0 siblings, 0 replies; 14+ messages in thread
From: Michael Ellerman @ 2019-11-14  8:48 UTC (permalink / raw)
  To: Christoph Hellwig, Nicolas Saenz Julienne, iommu, Russell King
  Cc: linuxppc-dev, linux-mips, linux-arm-kernel

Christoph Hellwig <hch@lst.de> writes:
> Support for calling the DMA API functions without a valid device pointer
> was removed a while ago, so remove the stale support for that from the
> powerpc __phys_to_dma / __dma_to_phys helpers.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/powerpc/include/asm/dma-direct.h | 4 ----
>  1 file changed, 4 deletions(-)

Acked-by: Michael Ellerman <mpe@ellerman.id.au>

cheers

> diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
> index e29e8a236b8d..abc154d784b0 100644
> --- a/arch/powerpc/include/asm/dma-direct.h
> +++ b/arch/powerpc/include/asm/dma-direct.h
> @@ -4,15 +4,11 @@
>  
>  static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>  {
> -	if (!dev)
> -		return paddr + PCI_DRAM_OFFSET;
>  	return paddr + dev->archdata.dma_offset;
>  }
>  
>  static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
>  {
> -	if (!dev)
> -		return daddr - PCI_DRAM_OFFSET;
>  	return daddr - dev->archdata.dma_offset;
>  }
>  #endif /* ASM_POWERPC_DMA_DIRECT_H */
> -- 
> 2.20.1

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

* Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
  2019-11-13  7:35 ` [PATCH 1/3] dma-direct: unify the dma_capable definitions Christoph Hellwig
  2019-11-14  8:47   ` Michael Ellerman
@ 2019-11-19  9:27   ` Marek Szyprowski
  2019-11-19  9:44     ` Krzysztof Kozlowski
  2019-11-19 10:19     ` Nicolas Saenz Julienne
  1 sibling, 2 replies; 14+ messages in thread
From: Marek Szyprowski @ 2019-11-19  9:27 UTC (permalink / raw)
  To: Christoph Hellwig, Nicolas Saenz Julienne, iommu, Russell King
  Cc: linuxppc-dev, linux-mips, linux-arm-kernel, Krzysztof Kozlowski,
	'Linux Samsung SOC'

Hi Christoph,

On 13.11.2019 08:35, Christoph Hellwig wrote:
> Currently each architectures that wants to override dma_to_phys and
> phys_to_dma also has to provide dma_capable.  But there isn't really
> any good reason for that.  powerpc and mips just have copies of the
> generic one minus the latests fix, and the arm one was the inspiration
> for said fix, but misses the bus_dma_mask handling.
> Make all architectures use the generic version instead.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

This patch breaks DMAengine PL330 driver on Samsung Exynos SoCs:

[    3.602338] dma-pl330 12690000.pdma: overflow 0x13810020+1 of DMA 
mask ffffffff bus mask 0
[    3.605113] ------------[ cut here ]------------
[    3.609719] WARNING: CPU: 2 PID: 1 at kernel/dma/direct.c:36 
report_addr+0xc0/0xfc
[    3.617226] Modules linked in:
[    3.620271] CPU: 2 PID: 1 Comm: init Not tainted 
5.4.0-rc5-00056-gb037b220e71d #6911
[    3.627986] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[    3.634094] [<c01124e8>] (unwind_backtrace) from [<c010dfcc>] 
(show_stack+0x10/0x14)
[    3.641803] [<c010dfcc>] (show_stack) from [<c0ae9af8>] 
(dump_stack+0xa8/0xd4)
[    3.649002] [<c0ae9af8>] (dump_stack) from [<c012746c>] 
(__warn+0xf4/0x10c)
[    3.655940] [<c012746c>] (__warn) from [<c0127534>] 
(warn_slowpath_fmt+0xb0/0xb8)
[    3.663404] [<c0127534>] (warn_slowpath_fmt) from [<c01b4ff4>] 
(report_addr+0xc0/0xfc)
[    3.671303] [<c01b4ff4>] (report_addr) from [<c01b5264>] 
(dma_direct_map_resource+0x98/0xa0)
[    3.679739] [<c01b5264>] (dma_direct_map_resource) from [<c04fbb58>] 
(pl330_prep_slave_fifo+0xe4/0x128)
[    3.689099] [<c04fbb58>] (pl330_prep_slave_fifo) from [<c04fe2b8>] 
(pl330_prep_slave_sg+0x54/0x1cc)
[    3.698129] [<c04fe2b8>] (pl330_prep_slave_sg) from [<c053e5f0>] 
(s3c24xx_serial_start_tx_dma+0x118/0x1e8)
[    3.707764] [<c053e5f0>] (s3c24xx_serial_start_tx_dma) from 
[<c0535f70>] (uart_write+0xe4/0x1e0)
[    3.716532] [<c0535f70>] (uart_write) from [<c05186a0>] 
(n_tty_write+0x1c8/0x474)
[    3.723992] [<c05186a0>] (n_tty_write) from [<c05163c0>] 
(tty_write+0x154/0x314)
[    3.731380] [<c05163c0>] (tty_write) from [<c02a5748>] 
(__vfs_write+0x30/0x1d0)
[    3.738662] [<c02a5748>] (__vfs_write) from [<c02a851c>] 
(vfs_write+0xa4/0x180)
[    3.745949] [<c02a851c>] (vfs_write) from [<c02a8778>] 
(ksys_write+0x60/0xd8)
[    3.753069] [<c02a8778>] (ksys_write) from [<c0101000>] 
(ret_fast_syscall+0x0/0x28)
[    3.760705] Exception stack(0xee8dffa8 to 0xee8dfff0)
[    3.765739] ffa0:                   0000004a beca876c 00000002 
beca876c 0000004a 00000000
[    3.773900] ffc0: 0000004a beca876c b6f02cf0 00000004 beca876c 
0000004a 00000000 b6f99010
[    3.782056] ffe0: 0000006c beca8628 b6e1d000 b6e7a634
[    3.787092] irq event stamp: 289740
[    3.790571] hardirqs last  enabled at (289739): [<c0b0d0c4>] 
_raw_spin_unlock_irqrestore+0x6c/0x74
[    3.799503] hardirqs last disabled at (289740): [<c0b0caf8>] 
_raw_spin_lock_irqsave+0x1c/0x58
[    3.808011] softirqs last  enabled at (289576): [<c01026bc>] 
__do_softirq+0x4fc/0x5fc
[    3.815830] softirqs last disabled at (289567): [<c0130044>] 
irq_exit+0x16c/0x170
[    3.823286] ---[ end trace b1432c658797b861 ]---
[    3.827898] samsung-uart 13810000.serial: Unable to get desc for Tx
[    3.834624] samsung-uart 13810000.serial: Unable to get desc for Tx
[    3.840487] samsung-uart 13810000.serial: Unable to get desc for Tx

I'm checking now which part of it causes the issue.


> ---
>   arch/arm/include/asm/dma-direct.h     | 19 -------------------
>   arch/mips/include/asm/dma-direct.h    |  8 --------
>   arch/powerpc/include/asm/dma-direct.h |  9 ---------
>   include/linux/dma-direct.h            |  2 +-
>   4 files changed, 1 insertion(+), 37 deletions(-)
>
> diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h
> index b67e5fc1fe43..7c3001a6a775 100644
> --- a/arch/arm/include/asm/dma-direct.h
> +++ b/arch/arm/include/asm/dma-direct.h
> @@ -14,23 +14,4 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
>   	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
>   }
>   
> -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
> -{
> -	u64 limit, mask;
> -
> -	if (!dev->dma_mask)
> -		return 0;
> -
> -	mask = *dev->dma_mask;
> -
> -	limit = (mask + 1) & ~mask;
> -	if (limit && size > limit)
> -		return 0;
> -
> -	if ((addr | (addr + size - 1)) & ~mask)
> -		return 0;
> -
> -	return 1;
> -}
> -
>   #endif /* ASM_ARM_DMA_DIRECT_H */
> diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h
> index b5c240806e1b..14e352651ce9 100644
> --- a/arch/mips/include/asm/dma-direct.h
> +++ b/arch/mips/include/asm/dma-direct.h
> @@ -2,14 +2,6 @@
>   #ifndef _MIPS_DMA_DIRECT_H
>   #define _MIPS_DMA_DIRECT_H 1
>   
> -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
> -{
> -	if (!dev->dma_mask)
> -		return false;
> -
> -	return addr + size - 1 <= *dev->dma_mask;
> -}
> -
>   dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
>   phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr);
>   
> diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
> index a2912b47102c..e29e8a236b8d 100644
> --- a/arch/powerpc/include/asm/dma-direct.h
> +++ b/arch/powerpc/include/asm/dma-direct.h
> @@ -2,15 +2,6 @@
>   #ifndef ASM_POWERPC_DMA_DIRECT_H
>   #define ASM_POWERPC_DMA_DIRECT_H 1
>   
> -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
> -{
> -	if (!dev->dma_mask)
> -		return false;
> -
> -	return addr + size - 1 <=
> -		min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
> -}
> -
>   static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
>   {
>   	if (!dev)
> diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
> index 6db863c3eb93..991f8aa2676e 100644
> --- a/include/linux/dma-direct.h
> +++ b/include/linux/dma-direct.h
> @@ -24,6 +24,7 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
>   
>   	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
>   }
> +#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
>   
>   static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
>   {
> @@ -38,7 +39,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
>   
>   	return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
>   }
> -#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
>   
>   #ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED
>   bool force_dma_unencrypted(struct device *dev);

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
  2019-11-19  9:27   ` Marek Szyprowski
@ 2019-11-19  9:44     ` Krzysztof Kozlowski
  2019-11-19 10:26       ` Marek Szyprowski
  2019-11-19 10:19     ` Nicolas Saenz Julienne
  1 sibling, 1 reply; 14+ messages in thread
From: Krzysztof Kozlowski @ 2019-11-19  9:44 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Christoph Hellwig, Nicolas Saenz Julienne, iommu, Russell King,
	linuxppc-dev, linux-mips, linux-arm-kernel, Linux Samsung SOC,
	Robin Gong, Vinod Koul

On Tue, 19 Nov 2019 at 17:27, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>
> Hi Christoph,
>
> On 13.11.2019 08:35, Christoph Hellwig wrote:
> > Currently each architectures that wants to override dma_to_phys and
> > phys_to_dma also has to provide dma_capable.  But there isn't really
> > any good reason for that.  powerpc and mips just have copies of the
> > generic one minus the latests fix, and the arm one was the inspiration
> > for said fix, but misses the bus_dma_mask handling.
> > Make all architectures use the generic version instead.
> >
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
>
> This patch breaks DMAengine PL330 driver on Samsung Exynos SoCs:


Thanks Marek for bisecting it. I wonder whether it is also the cause
for boot failures I see on NXP Vybrid VF50 SoC (NXP/Freescale
fsl-edma) since few days:

[ 2.853428] fsl-edma 40018000.dma-controller: overflow 0x40027007+1 of
DMA mask ffffffff bus mask 0
[ 2.862566] ------------[ cut here ]------------
[ 2.867273] WARNING: CPU: 0 PID: 1 at
/home/buildbot/worker/builddir_yocto/build/build/tmp/work-shared/col-vf50-proceq-mainline-next/kernel-source/kernel/dma/direct.c:35
report_addr+0xc0/0xfc
[ 2.884380] Modules linked in:
[ 2.887486] CPU: 0 PID: 1 Comm: swapper Tainted: G W
5.4.0-rc7-next-20191118-g519ead8f6a32 #1
[ 2.897364] Hardware name: Freescale Vybrid VF5xx/VF6xx (Device Tree)
[ 2.903892] [<8010ddfc>] (unwind_backtrace) from [<8010b4b8>]
(show_stack+0x10/0x14)
[ 2.911712] [<8010b4b8>] (show_stack) from [<8011b08c>] (__warn+0xd4/0xec)
[ 2.918653] [<8011b08c>] (__warn) from [<8011b154>]
(warn_slowpath_fmt+0xb0/0xb8)
[ 2.926218] [<8011b154>] (warn_slowpath_fmt) from [<80155f7c>]
(report_addr+0xc0/0xfc)
[ 2.934221] [<80155f7c>] (report_addr) from [<801561f0>]
(dma_direct_map_resource+0x98/0xa4)
[ 2.942744] [<801561f0>] (dma_direct_map_resource) from [<8041d5d4>]
(fsl_edma_prep_slave_dma+0x12c/0x150)
[ 2.952475] [<8041d5d4>] (fsl_edma_prep_slave_dma) from [<8041d8cc>]
(fsl_edma_prep_dma_cyclic+0x30/0x21c)
[ 2.962213] [<8041d8cc>] (fsl_edma_prep_dma_cyclic) from [<80452e10>]
(lpuart_rx_dma_startup+0x188/0x36c)
[ 2.971871] [<80452e10>] (lpuart_rx_dma_startup) from [<80453058>]
(lpuart_startup+0x64/0x78)
[ 2.980477] [<80453058>] (lpuart_startup) from [<8044e924>]
(uart_startup.part.7+0x110/0x23c)
[ 2.989080] [<8044e924>] (uart_startup.part.7) from [<8044eaa0>]
(uart_port_activate+0x50/0x7c)
[ 2.997857] [<8044eaa0>] (uart_port_activate) from [<80438dc0>]
(tty_port_open+0x74/0xc0)
[ 3.006111] [<80438dc0>] (tty_port_open) from [<8044be30>] (uart_open+0x18/0x20)
[ 3.013588] [<8044be30>] (uart_open) from [<80431b4c>] (tty_open+0x108/0x428)
[ 3.020794] [<80431b4c>] (tty_open) from [<801edb48>] (chrdev_open+0xac/0x164)
[ 3.028098] [<801edb48>] (chrdev_open) from [<801e55c8>]
(do_dentry_open+0x22c/0x3e4)
[ 3.036010] [<801e55c8>] (do_dentry_open) from [<801f72a8>]
(path_openat+0x4a4/0xf78)
[ 3.043912] [<801f72a8>] (path_openat) from [<801f8d34>]
(do_filp_open+0x70/0xdc)
[ 3.051472] [<801f8d34>] (do_filp_open) from [<801e6998>]
(do_sys_open+0x128/0x1f4)
[ 3.059217] [<801e6998>] (do_sys_open) from [<80a00ee0>]
(kernel_init_freeable+0x150/0x1c4)
[ 3.067658] [<80a00ee0>] (kernel_init_freeable) from [<8068e208>]
(kernel_init+0x8/0x110)
[ 3.075917] [<8068e208>] (kernel_init) from [<801010e8>]
(ret_from_fork+0x14/0x2c)
[ 3.083539] Exception stack(0x86843fb0 to 0x86843ff8)
[ 3.088631] 3fa0: 00000000 00000000 00000000 00000000
[ 3.096866] 3fc0: 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000
[ 3.105103] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[ 3.111752] ---[ end trace 6fb699802256a309 ]---
[    3.116423] fsl-lpuart 40027000.serial: Cannot prepare cyclic DMA
[    3.192968] VFS: Mounted root (nfs4 filesystem) on device 0:13.
[    3.201432] devtmpfs: mounted
[    3.210985] Freeing unused kernel memory: 1024K
[    3.217854] Run /sbin/init as init process
[    4.643355] systemd[1]: System time before build time, advancing clock.
[    4.774106] random: systemd: uninitialized urandom read (16 bytes read)
[    4.838361] systemd[1]: systemd 232 running in system mode. (-PAM
-AUDIT -SELINUX -IMA -APPARMOR -SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP
-GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN)
[    4.858997] systemd[1]: Detected architecture arm.
[    4.873438] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
[    4.880138] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
[    4.886585] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
[    4.893124] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
[    4.899679] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
[    4.906110] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
[    4.912616] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!

Although maybe that's just the fsl-edma problem?

Best regards,
Krzysztof

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

* Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
  2019-11-19  9:27   ` Marek Szyprowski
  2019-11-19  9:44     ` Krzysztof Kozlowski
@ 2019-11-19 10:19     ` Nicolas Saenz Julienne
  1 sibling, 0 replies; 14+ messages in thread
From: Nicolas Saenz Julienne @ 2019-11-19 10:19 UTC (permalink / raw)
  To: Marek Szyprowski, Christoph Hellwig, iommu, Russell King
  Cc: linuxppc-dev, linux-mips, linux-arm-kernel, Krzysztof Kozlowski,
	'Linux Samsung SOC'

[-- Attachment #1: Type: text/plain, Size: 7426 bytes --]

On Tue, 2019-11-19 at 10:27 +0100, Marek Szyprowski wrote:
> Hi Christoph,
> 
> On 13.11.2019 08:35, Christoph Hellwig wrote:
> > Currently each architectures that wants to override dma_to_phys and
> > phys_to_dma also has to provide dma_capable.  But there isn't really
> > any good reason for that.  powerpc and mips just have copies of the
> > generic one minus the latests fix, and the arm one was the inspiration
> > for said fix, but misses the bus_dma_mask handling.
> > Make all architectures use the generic version instead.
> > 
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> This patch breaks DMAengine PL330 driver on Samsung Exynos SoCs:
> 
> [    3.602338] dma-pl330 12690000.pdma: overflow 0x13810020+1 of DMA 
> mask ffffffff bus mask 0
> [    3.605113] ------------[ cut here ]------------
> [    3.609719] WARNING: CPU: 2 PID: 1 at kernel/dma/direct.c:36 
> report_addr+0xc0/0xfc
> [    3.617226] Modules linked in:
> [    3.620271] CPU: 2 PID: 1 Comm: init Not tainted 
> 5.4.0-rc5-00056-gb037b220e71d #6911
> [    3.627986] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
> [    3.634094] [<c01124e8>] (unwind_backtrace) from [<c010dfcc>] 
> (show_stack+0x10/0x14)
> [    3.641803] [<c010dfcc>] (show_stack) from [<c0ae9af8>] 
> (dump_stack+0xa8/0xd4)
> [    3.649002] [<c0ae9af8>] (dump_stack) from [<c012746c>] 
> (__warn+0xf4/0x10c)
> [    3.655940] [<c012746c>] (__warn) from [<c0127534>] 
> (warn_slowpath_fmt+0xb0/0xb8)
> [    3.663404] [<c0127534>] (warn_slowpath_fmt) from [<c01b4ff4>] 
> (report_addr+0xc0/0xfc)
> [    3.671303] [<c01b4ff4>] (report_addr) from [<c01b5264>] 
> (dma_direct_map_resource+0x98/0xa0)
> [    3.679739] [<c01b5264>] (dma_direct_map_resource) from [<c04fbb58>] 
> (pl330_prep_slave_fifo+0xe4/0x128)
> [    3.689099] [<c04fbb58>] (pl330_prep_slave_fifo) from [<c04fe2b8>] 
> (pl330_prep_slave_sg+0x54/0x1cc)
> [    3.698129] [<c04fe2b8>] (pl330_prep_slave_sg) from [<c053e5f0>] 
> (s3c24xx_serial_start_tx_dma+0x118/0x1e8)
> [    3.707764] [<c053e5f0>] (s3c24xx_serial_start_tx_dma) from 
> [<c0535f70>] (uart_write+0xe4/0x1e0)
> [    3.716532] [<c0535f70>] (uart_write) from [<c05186a0>] 
> (n_tty_write+0x1c8/0x474)
> [    3.723992] [<c05186a0>] (n_tty_write) from [<c05163c0>] 
> (tty_write+0x154/0x314)
> [    3.731380] [<c05163c0>] (tty_write) from [<c02a5748>] 
> (__vfs_write+0x30/0x1d0)
> [    3.738662] [<c02a5748>] (__vfs_write) from [<c02a851c>] 
> (vfs_write+0xa4/0x180)
> [    3.745949] [<c02a851c>] (vfs_write) from [<c02a8778>] 
> (ksys_write+0x60/0xd8)
> [    3.753069] [<c02a8778>] (ksys_write) from [<c0101000>] 
> (ret_fast_syscall+0x0/0x28)
> [    3.760705] Exception stack(0xee8dffa8 to 0xee8dfff0)
> [    3.765739] ffa0:                   0000004a beca876c 00000002 
> beca876c 0000004a 00000000
> [    3.773900] ffc0: 0000004a beca876c b6f02cf0 00000004 beca876c 
> 0000004a 00000000 b6f99010
> [    3.782056] ffe0: 0000006c beca8628 b6e1d000 b6e7a634
> [    3.787092] irq event stamp: 289740
> [    3.790571] hardirqs last  enabled at (289739): [<c0b0d0c4>] 
> _raw_spin_unlock_irqrestore+0x6c/0x74
> [    3.799503] hardirqs last disabled at (289740): [<c0b0caf8>] 
> _raw_spin_lock_irqsave+0x1c/0x58
> [    3.808011] softirqs last  enabled at (289576): [<c01026bc>] 
> __do_softirq+0x4fc/0x5fc
> [    3.815830] softirqs last disabled at (289567): [<c0130044>] 
> irq_exit+0x16c/0x170
> [    3.823286] ---[ end trace b1432c658797b861 ]---
> [    3.827898] samsung-uart 13810000.serial: Unable to get desc for Tx
> [    3.834624] samsung-uart 13810000.serial: Unable to get desc for Tx
> [    3.840487] samsung-uart 13810000.serial: Unable to get desc for Tx
> 
> I'm checking now which part of it causes the issue.

Hi Marek,
is this a on a non LPAE ARM32 device?

Regards,
Nicolas

> > ---
> >   arch/arm/include/asm/dma-direct.h     | 19 -------------------
> >   arch/mips/include/asm/dma-direct.h    |  8 --------
> >   arch/powerpc/include/asm/dma-direct.h |  9 ---------
> >   include/linux/dma-direct.h            |  2 +-
> >   4 files changed, 1 insertion(+), 37 deletions(-)
> > 
> > diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-
> > direct.h
> > index b67e5fc1fe43..7c3001a6a775 100644
> > --- a/arch/arm/include/asm/dma-direct.h
> > +++ b/arch/arm/include/asm/dma-direct.h
> > @@ -14,23 +14,4 @@ static inline phys_addr_t __dma_to_phys(struct device
> > *dev, dma_addr_t dev_addr)
> >   	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
> >   }
> >   
> > -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t
> > size)
> > -{
> > -	u64 limit, mask;
> > -
> > -	if (!dev->dma_mask)
> > -		return 0;
> > -
> > -	mask = *dev->dma_mask;
> > -
> > -	limit = (mask + 1) & ~mask;
> > -	if (limit && size > limit)
> > -		return 0;
> > -
> > -	if ((addr | (addr + size - 1)) & ~mask)
> > -		return 0;
> > -
> > -	return 1;
> > -}
> > -
> >   #endif /* ASM_ARM_DMA_DIRECT_H */
> > diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-
> > direct.h
> > index b5c240806e1b..14e352651ce9 100644
> > --- a/arch/mips/include/asm/dma-direct.h
> > +++ b/arch/mips/include/asm/dma-direct.h
> > @@ -2,14 +2,6 @@
> >   #ifndef _MIPS_DMA_DIRECT_H
> >   #define _MIPS_DMA_DIRECT_H 1
> >   
> > -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t
> > size)
> > -{
> > -	if (!dev->dma_mask)
> > -		return false;
> > -
> > -	return addr + size - 1 <= *dev->dma_mask;
> > -}
> > -
> >   dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
> >   phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr);
> >   
> > diff --git a/arch/powerpc/include/asm/dma-direct.h
> > b/arch/powerpc/include/asm/dma-direct.h
> > index a2912b47102c..e29e8a236b8d 100644
> > --- a/arch/powerpc/include/asm/dma-direct.h
> > +++ b/arch/powerpc/include/asm/dma-direct.h
> > @@ -2,15 +2,6 @@
> >   #ifndef ASM_POWERPC_DMA_DIRECT_H
> >   #define ASM_POWERPC_DMA_DIRECT_H 1
> >   
> > -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t
> > size)
> > -{
> > -	if (!dev->dma_mask)
> > -		return false;
> > -
> > -	return addr + size - 1 <=
> > -		min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
> > -}
> > -
> >   static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t
> > paddr)
> >   {
> >   	if (!dev)
> > diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
> > index 6db863c3eb93..991f8aa2676e 100644
> > --- a/include/linux/dma-direct.h
> > +++ b/include/linux/dma-direct.h
> > @@ -24,6 +24,7 @@ static inline phys_addr_t __dma_to_phys(struct device
> > *dev, dma_addr_t dev_addr)
> >   
> >   	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
> >   }
> > +#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
> >   
> >   static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t
> > size)
> >   {
> > @@ -38,7 +39,6 @@ static inline bool dma_capable(struct device *dev,
> > dma_addr_t addr, size_t size)
> >   
> >   	return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
> >   }
> > -#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
> >   
> >   #ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED
> >   bool force_dma_unencrypted(struct device *dev);
> 
> Best regards


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
  2019-11-19  9:44     ` Krzysztof Kozlowski
@ 2019-11-19 10:26       ` Marek Szyprowski
  2019-11-19 16:16         ` Robin Murphy
  2019-11-19 16:46         ` Christoph Hellwig
  0 siblings, 2 replies; 14+ messages in thread
From: Marek Szyprowski @ 2019-11-19 10:26 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Christoph Hellwig, Nicolas Saenz Julienne, iommu, Russell King,
	linuxppc-dev, linux-mips, linux-arm-kernel, Linux Samsung SOC,
	Robin Gong, Vinod Koul

Hi Krzysztof,

On 19.11.2019 10:44, Krzysztof Kozlowski wrote:
> On Tue, 19 Nov 2019 at 17:27, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>> Hi Christoph,
>>
>> On 13.11.2019 08:35, Christoph Hellwig wrote:
>>> Currently each architectures that wants to override dma_to_phys and
>>> phys_to_dma also has to provide dma_capable.  But there isn't really
>>> any good reason for that.  powerpc and mips just have copies of the
>>> generic one minus the latests fix, and the arm one was the inspiration
>>> for said fix, but misses the bus_dma_mask handling.
>>> Make all architectures use the generic version instead.
>>>
>>> Signed-off-by: Christoph Hellwig <hch@lst.de>
>> This patch breaks DMAengine PL330 driver on Samsung Exynos SoCs:
>
> Thanks Marek for bisecting it. I wonder whether it is also the cause
> for boot failures I see on NXP Vybrid VF50 SoC (NXP/Freescale
> fsl-edma) since few days:
>
> [ 2.853428] fsl-edma 40018000.dma-controller: overflow 0x40027007+1 of
> DMA mask ffffffff bus mask 0
> [ 2.862566] ------------[ cut here ]------------
> [ 2.867273] WARNING: CPU: 0 PID: 1 at
> /home/buildbot/worker/builddir_yocto/build/build/tmp/work-shared/col-vf50-proceq-mainline-next/kernel-source/kernel/dma/direct.c:35
> report_addr+0xc0/0xfc
> [ 2.884380] Modules linked in:
> [ 2.887486] CPU: 0 PID: 1 Comm: swapper Tainted: G W
> 5.4.0-rc7-next-20191118-g519ead8f6a32 #1
> [ 2.897364] Hardware name: Freescale Vybrid VF5xx/VF6xx (Device Tree)
> [ 2.903892] [<8010ddfc>] (unwind_backtrace) from [<8010b4b8>]
> (show_stack+0x10/0x14)
> [ 2.911712] [<8010b4b8>] (show_stack) from [<8011b08c>] (__warn+0xd4/0xec)
> [ 2.918653] [<8011b08c>] (__warn) from [<8011b154>]
> (warn_slowpath_fmt+0xb0/0xb8)
> [ 2.926218] [<8011b154>] (warn_slowpath_fmt) from [<80155f7c>]
> (report_addr+0xc0/0xfc)
> [ 2.934221] [<80155f7c>] (report_addr) from [<801561f0>]
> (dma_direct_map_resource+0x98/0xa4)
> [ 2.942744] [<801561f0>] (dma_direct_map_resource) from [<8041d5d4>]
> (fsl_edma_prep_slave_dma+0x12c/0x150)
> [ 2.952475] [<8041d5d4>] (fsl_edma_prep_slave_dma) from [<8041d8cc>]
> (fsl_edma_prep_dma_cyclic+0x30/0x21c)
> [ 2.962213] [<8041d8cc>] (fsl_edma_prep_dma_cyclic) from [<80452e10>]
> (lpuart_rx_dma_startup+0x188/0x36c)
> [ 2.971871] [<80452e10>] (lpuart_rx_dma_startup) from [<80453058>]
> (lpuart_startup+0x64/0x78)
> [ 2.980477] [<80453058>] (lpuart_startup) from [<8044e924>]
> (uart_startup.part.7+0x110/0x23c)
> [ 2.989080] [<8044e924>] (uart_startup.part.7) from [<8044eaa0>]
> (uart_port_activate+0x50/0x7c)
> [ 2.997857] [<8044eaa0>] (uart_port_activate) from [<80438dc0>]
> (tty_port_open+0x74/0xc0)
> [ 3.006111] [<80438dc0>] (tty_port_open) from [<8044be30>] (uart_open+0x18/0x20)
> [ 3.013588] [<8044be30>] (uart_open) from [<80431b4c>] (tty_open+0x108/0x428)
> [ 3.020794] [<80431b4c>] (tty_open) from [<801edb48>] (chrdev_open+0xac/0x164)
> [ 3.028098] [<801edb48>] (chrdev_open) from [<801e55c8>]
> (do_dentry_open+0x22c/0x3e4)
> [ 3.036010] [<801e55c8>] (do_dentry_open) from [<801f72a8>]
> (path_openat+0x4a4/0xf78)
> [ 3.043912] [<801f72a8>] (path_openat) from [<801f8d34>]
> (do_filp_open+0x70/0xdc)
> [ 3.051472] [<801f8d34>] (do_filp_open) from [<801e6998>]
> (do_sys_open+0x128/0x1f4)
> [ 3.059217] [<801e6998>] (do_sys_open) from [<80a00ee0>]
> (kernel_init_freeable+0x150/0x1c4)
> [ 3.067658] [<80a00ee0>] (kernel_init_freeable) from [<8068e208>]
> (kernel_init+0x8/0x110)
> [ 3.075917] [<8068e208>] (kernel_init) from [<801010e8>]
> (ret_from_fork+0x14/0x2c)
> [ 3.083539] Exception stack(0x86843fb0 to 0x86843ff8)
> [ 3.088631] 3fa0: 00000000 00000000 00000000 00000000
> [ 3.096866] 3fc0: 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000
> [ 3.105103] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [ 3.111752] ---[ end trace 6fb699802256a309 ]---
> [    3.116423] fsl-lpuart 40027000.serial: Cannot prepare cyclic DMA
> [    3.192968] VFS: Mounted root (nfs4 filesystem) on device 0:13.
> [    3.201432] devtmpfs: mounted
> [    3.210985] Freeing unused kernel memory: 1024K
> [    3.217854] Run /sbin/init as init process
> [    4.643355] systemd[1]: System time before build time, advancing clock.
> [    4.774106] random: systemd: uninitialized urandom read (16 bytes read)
> [    4.838361] systemd[1]: systemd 232 running in system mode. (-PAM
> -AUDIT -SELINUX -IMA -APPARMOR -SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP
> -GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN)
> [    4.858997] systemd[1]: Detected architecture arm.
> [    4.873438] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
> [    4.880138] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
> [    4.886585] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
> [    4.893124] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
> [    4.899679] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
> [    4.906110] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
> [    4.912616] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
>
> Although maybe that's just the fsl-edma problem?

This is the same issue.

A quick looks at the dma-direct code revealed that the 
dma_direct_map_resource() is broken after this unification, because it 
calls dma_direct_possible(), which then calls dma_capable(). The generic 
dma_capable() from include/linux/dma-direct.h checks if the provided 
address is in RAM memory range, what in the case of 
dma_direct_map_resource() is not true.

A quick fix for this issue is to inline dma_direct_possible() with a 
modified dma_capable() directly to the dma_direct_map_resource() 
function (without the min_low_pfn check):

diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 077876ae5c74..b6dd6a0b338b 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -411,8 +411,10 @@ dma_addr_t dma_direct_map_resource(struct device 
*dev, phys_addr_t paddr,
                 size_t size, enum dma_data_direction dir, unsigned long 
attrs)
  {
         dma_addr_t dma_addr = paddr;
+       dma_addr_t end = dma_addr + size - 1;

-       if (unlikely(!dma_direct_possible(dev, dma_addr, size))) {
+       if (unlikely(swiotlb_force == SWIOTLB_FORCE || !dev->dma_mask ||
+                    end > min_not_zero(*dev->dma_mask, 
dev->bus_dma_mask))) {
                 report_addr(dev, dma_addr, size);
                 return DMA_MAPPING_ERROR;
         }

Christoph: Let me know if this is a proper fix for you, then I will send 
it as a full patch.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
  2019-11-19 10:26       ` Marek Szyprowski
@ 2019-11-19 16:16         ` Robin Murphy
  2019-11-19 16:46         ` Christoph Hellwig
  1 sibling, 0 replies; 14+ messages in thread
From: Robin Murphy @ 2019-11-19 16:16 UTC (permalink / raw)
  To: Marek Szyprowski, Krzysztof Kozlowski
  Cc: Vinod Koul, Linux Samsung SOC, linux-mips, Russell King, iommu,
	linux-arm-kernel, Robin Gong, linuxppc-dev, Christoph Hellwig,
	Nicolas Saenz Julienne

On 19/11/2019 10:26 am, Marek Szyprowski wrote:
> Hi Krzysztof,
> 
> On 19.11.2019 10:44, Krzysztof Kozlowski wrote:
>> On Tue, 19 Nov 2019 at 17:27, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>>> Hi Christoph,
>>>
>>> On 13.11.2019 08:35, Christoph Hellwig wrote:
>>>> Currently each architectures that wants to override dma_to_phys and
>>>> phys_to_dma also has to provide dma_capable.  But there isn't really
>>>> any good reason for that.  powerpc and mips just have copies of the
>>>> generic one minus the latests fix, and the arm one was the inspiration
>>>> for said fix, but misses the bus_dma_mask handling.
>>>> Make all architectures use the generic version instead.
>>>>
>>>> Signed-off-by: Christoph Hellwig <hch@lst.de>
>>> This patch breaks DMAengine PL330 driver on Samsung Exynos SoCs:
>>
>> Thanks Marek for bisecting it. I wonder whether it is also the cause
>> for boot failures I see on NXP Vybrid VF50 SoC (NXP/Freescale
>> fsl-edma) since few days:
>>
>> [ 2.853428] fsl-edma 40018000.dma-controller: overflow 0x40027007+1 of
>> DMA mask ffffffff bus mask 0
>> [ 2.862566] ------------[ cut here ]------------
>> [ 2.867273] WARNING: CPU: 0 PID: 1 at
>> /home/buildbot/worker/builddir_yocto/build/build/tmp/work-shared/col-vf50-proceq-mainline-next/kernel-source/kernel/dma/direct.c:35
>> report_addr+0xc0/0xfc
>> [ 2.884380] Modules linked in:
>> [ 2.887486] CPU: 0 PID: 1 Comm: swapper Tainted: G W
>> 5.4.0-rc7-next-20191118-g519ead8f6a32 #1
>> [ 2.897364] Hardware name: Freescale Vybrid VF5xx/VF6xx (Device Tree)
>> [ 2.903892] [<8010ddfc>] (unwind_backtrace) from [<8010b4b8>]
>> (show_stack+0x10/0x14)
>> [ 2.911712] [<8010b4b8>] (show_stack) from [<8011b08c>] (__warn+0xd4/0xec)
>> [ 2.918653] [<8011b08c>] (__warn) from [<8011b154>]
>> (warn_slowpath_fmt+0xb0/0xb8)
>> [ 2.926218] [<8011b154>] (warn_slowpath_fmt) from [<80155f7c>]
>> (report_addr+0xc0/0xfc)
>> [ 2.934221] [<80155f7c>] (report_addr) from [<801561f0>]
>> (dma_direct_map_resource+0x98/0xa4)
>> [ 2.942744] [<801561f0>] (dma_direct_map_resource) from [<8041d5d4>]
>> (fsl_edma_prep_slave_dma+0x12c/0x150)
>> [ 2.952475] [<8041d5d4>] (fsl_edma_prep_slave_dma) from [<8041d8cc>]
>> (fsl_edma_prep_dma_cyclic+0x30/0x21c)
>> [ 2.962213] [<8041d8cc>] (fsl_edma_prep_dma_cyclic) from [<80452e10>]
>> (lpuart_rx_dma_startup+0x188/0x36c)
>> [ 2.971871] [<80452e10>] (lpuart_rx_dma_startup) from [<80453058>]
>> (lpuart_startup+0x64/0x78)
>> [ 2.980477] [<80453058>] (lpuart_startup) from [<8044e924>]
>> (uart_startup.part.7+0x110/0x23c)
>> [ 2.989080] [<8044e924>] (uart_startup.part.7) from [<8044eaa0>]
>> (uart_port_activate+0x50/0x7c)
>> [ 2.997857] [<8044eaa0>] (uart_port_activate) from [<80438dc0>]
>> (tty_port_open+0x74/0xc0)
>> [ 3.006111] [<80438dc0>] (tty_port_open) from [<8044be30>] (uart_open+0x18/0x20)
>> [ 3.013588] [<8044be30>] (uart_open) from [<80431b4c>] (tty_open+0x108/0x428)
>> [ 3.020794] [<80431b4c>] (tty_open) from [<801edb48>] (chrdev_open+0xac/0x164)
>> [ 3.028098] [<801edb48>] (chrdev_open) from [<801e55c8>]
>> (do_dentry_open+0x22c/0x3e4)
>> [ 3.036010] [<801e55c8>] (do_dentry_open) from [<801f72a8>]
>> (path_openat+0x4a4/0xf78)
>> [ 3.043912] [<801f72a8>] (path_openat) from [<801f8d34>]
>> (do_filp_open+0x70/0xdc)
>> [ 3.051472] [<801f8d34>] (do_filp_open) from [<801e6998>]
>> (do_sys_open+0x128/0x1f4)
>> [ 3.059217] [<801e6998>] (do_sys_open) from [<80a00ee0>]
>> (kernel_init_freeable+0x150/0x1c4)
>> [ 3.067658] [<80a00ee0>] (kernel_init_freeable) from [<8068e208>]
>> (kernel_init+0x8/0x110)
>> [ 3.075917] [<8068e208>] (kernel_init) from [<801010e8>]
>> (ret_from_fork+0x14/0x2c)
>> [ 3.083539] Exception stack(0x86843fb0 to 0x86843ff8)
>> [ 3.088631] 3fa0: 00000000 00000000 00000000 00000000
>> [ 3.096866] 3fc0: 00000000 00000000 00000000 00000000 00000000
>> 00000000 00000000 00000000
>> [ 3.105103] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>> [ 3.111752] ---[ end trace 6fb699802256a309 ]---
>> [    3.116423] fsl-lpuart 40027000.serial: Cannot prepare cyclic DMA
>> [    3.192968] VFS: Mounted root (nfs4 filesystem) on device 0:13.
>> [    3.201432] devtmpfs: mounted
>> [    3.210985] Freeing unused kernel memory: 1024K
>> [    3.217854] Run /sbin/init as init process
>> [    4.643355] systemd[1]: System time before build time, advancing clock.
>> [    4.774106] random: systemd: uninitialized urandom read (16 bytes read)
>> [    4.838361] systemd[1]: systemd 232 running in system mode. (-PAM
>> -AUDIT -SELINUX -IMA -APPARMOR -SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP
>> -GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN)
>> [    4.858997] systemd[1]: Detected architecture arm.
>> [    4.873438] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
>> [    4.880138] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
>> [    4.886585] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
>> [    4.893124] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
>> [    4.899679] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
>> [    4.906110] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
>> [    4.912616] fsl-lpuart 40027000.serial: Cannot prepare TX slave DMA!
>>
>> Although maybe that's just the fsl-edma problem?
> 
> This is the same issue.
> 
> A quick looks at the dma-direct code revealed that the
> dma_direct_map_resource() is broken after this unification, because it
> calls dma_direct_possible(), which then calls dma_capable(). The generic
> dma_capable() from include/linux/dma-direct.h checks if the provided
> address is in RAM memory range, what in the case of
> dma_direct_map_resource() is not true.
> 
> A quick fix for this issue is to inline dma_direct_possible() with a
> modified dma_capable() directly to the dma_direct_map_resource()
> function (without the min_low_pfn check):
> 
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index 077876ae5c74..b6dd6a0b338b 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -411,8 +411,10 @@ dma_addr_t dma_direct_map_resource(struct device
> *dev, phys_addr_t paddr,
>                   size_t size, enum dma_data_direction dir, unsigned long
> attrs)
>    {
>           dma_addr_t dma_addr = paddr;
> +       dma_addr_t end = dma_addr + size - 1;
> 
> -       if (unlikely(!dma_direct_possible(dev, dma_addr, size))) {
> +       if (unlikely(swiotlb_force == SWIOTLB_FORCE || !dev->dma_mask ||

You don't want the swiotlb_force check in there - we can't bounce-buffer 
device-to-device accesses, regardless of the SWIOTLB policy.

Robin.

> +                    end > min_not_zero(*dev->dma_mask,
> dev->bus_dma_mask))) {
>                   report_addr(dev, dma_addr, size);
>                   return DMA_MAPPING_ERROR;
>           }
> 
> Christoph: Let me know if this is a proper fix for you, then I will send
> it as a full patch.
> 
> Best regards
> 

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

* Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
  2019-11-19 10:26       ` Marek Szyprowski
  2019-11-19 16:16         ` Robin Murphy
@ 2019-11-19 16:46         ` Christoph Hellwig
  2019-11-20  6:31           ` Marek Szyprowski
  1 sibling, 1 reply; 14+ messages in thread
From: Christoph Hellwig @ 2019-11-19 16:46 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Krzysztof Kozlowski, Christoph Hellwig, Nicolas Saenz Julienne,
	iommu, Russell King, linuxppc-dev, linux-mips, linux-arm-kernel,
	Linux Samsung SOC, Robin Gong, Vinod Koul

[-- Attachment #1: Type: text/plain, Size: 336 bytes --]

On Tue, Nov 19, 2019 at 11:26:39AM +0100, Marek Szyprowski wrote:
> Christoph: Let me know if this is a proper fix for you, then I will send 
> it as a full patch.

Besides the point from Robin, which is really older than you patch
I'm not a fan of duplicating dma_capable here.  Let me know what you
think of the two attached patches.

[-- Attachment #2: 0001-dma-direct-don-t-check-swiotlb-force-in-dma_direct_m.patch --]
[-- Type: text/x-patch, Size: 1076 bytes --]

From db897c2ec63e7af78137c533c9f821c594896167 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Tue, 19 Nov 2019 17:35:36 +0100
Subject: dma-direct: don't check swiotlb=force in dma_direct_map_resource

When mapping resources we can't just use swiotlb ram for bounce
buffering.  Switch to a direct dma_capable check instead.

Fixes: cfced786969c ("dma-mapping: remove the default map_resource implementation")
Reported-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 kernel/dma/direct.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 077876ae5c74..a479bd2d1e8b 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -412,7 +412,7 @@ dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr,
 {
 	dma_addr_t dma_addr = paddr;
 
-	if (unlikely(!dma_direct_possible(dev, dma_addr, size))) {
+	if (unlikely(!dma_capable(dev, dma_addr, size))) {
 		report_addr(dev, dma_addr, size);
 		return DMA_MAPPING_ERROR;
 	}
-- 
2.20.1


[-- Attachment #3: 0002-dma-direct-exclude-dma_direct_map_resource-from-the-.patch --]
[-- Type: text/x-patch, Size: 4755 bytes --]

From fd82d238a42e3a5f12dd0621db2c724b89509b02 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Tue, 19 Nov 2019 17:38:58 +0100
Subject: dma-direct: exclude dma_direct_map_resource from the min_low_pfn
 check

The valid memory address check in dma_capable only makes sense when mapping
normal memory, not when using dma_map_resource to map a device resource.
Add a new boolean argument to dma_capable to exclude that check for the
dma_map_resource case.

Fixes: b12d66278dd6 ("dma-direct: check for overflows on 32 bit DMA addresses")
Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/x86/kernel/amd_gart_64.c | 4 ++--
 drivers/xen/swiotlb-xen.c     | 4 ++--
 include/linux/dma-direct.h    | 5 +++--
 kernel/dma/direct.c           | 4 ++--
 kernel/dma/swiotlb.c          | 2 +-
 5 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index a6ac3712db8b..5cfab41e8509 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -185,13 +185,13 @@ static void iommu_full(struct device *dev, size_t size, int dir)
 static inline int
 need_iommu(struct device *dev, unsigned long addr, size_t size)
 {
-	return force_iommu || !dma_capable(dev, addr, size);
+	return force_iommu || !dma_capable(dev, addr, size, true);
 }
 
 static inline int
 nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
 {
-	return !dma_capable(dev, addr, size);
+	return !dma_capable(dev, addr, size, true);
 }
 
 /* Map a single continuous physical area into the IOMMU.
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 3f8b2cdb4acb..b6d27762c6f8 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -375,7 +375,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 	 * we can safely return the device addr and not worry about bounce
 	 * buffering it.
 	 */
-	if (dma_capable(dev, dev_addr, size) &&
+	if (dma_capable(dev, dev_addr, size, true) &&
 	    !range_straddles_page_boundary(phys, size) &&
 		!xen_arch_need_swiotlb(dev, phys, dev_addr) &&
 		swiotlb_force != SWIOTLB_FORCE)
@@ -397,7 +397,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 	/*
 	 * Ensure that the address returned is DMA'ble
 	 */
-	if (unlikely(!dma_capable(dev, dev_addr, size))) {
+	if (unlikely(!dma_capable(dev, dev_addr, size, true))) {
 		swiotlb_tbl_unmap_single(dev, map, size, size, dir,
 				attrs | DMA_ATTR_SKIP_CPU_SYNC);
 		return DMA_MAPPING_ERROR;
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index f8959f75e496..99b77dd5f79b 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -49,14 +49,15 @@ 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)
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size,
+		bool is_ram)
 {
 	dma_addr_t end = addr + size - 1;
 
 	if (!dev->dma_mask)
 		return false;
 
-	if (!IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) &&
+	if (is_ram && !IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) &&
 	    min(addr, end) < phys_to_dma(dev, PFN_PHYS(min_low_pfn)))
 		return false;
 
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index a479bd2d1e8b..40f1f0aac4b1 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -363,7 +363,7 @@ static inline bool dma_direct_possible(struct device *dev, dma_addr_t dma_addr,
 		size_t size)
 {
 	return swiotlb_force != SWIOTLB_FORCE &&
-		dma_capable(dev, dma_addr, size);
+		dma_capable(dev, dma_addr, size, true);
 }
 
 dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
@@ -412,7 +412,7 @@ dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr,
 {
 	dma_addr_t dma_addr = paddr;
 
-	if (unlikely(!dma_capable(dev, dma_addr, size))) {
+	if (unlikely(!dma_capable(dev, dma_addr, size, false))) {
 		report_addr(dev, dma_addr, size);
 		return DMA_MAPPING_ERROR;
 	}
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index 673a2cdb2656..9280d6f8271e 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -678,7 +678,7 @@ bool swiotlb_map(struct device *dev, phys_addr_t *phys, dma_addr_t *dma_addr,
 
 	/* Ensure that the address returned is DMA'ble */
 	*dma_addr = __phys_to_dma(dev, *phys);
-	if (unlikely(!dma_capable(dev, *dma_addr, size))) {
+	if (unlikely(!dma_capable(dev, *dma_addr, size, true))) {
 		swiotlb_tbl_unmap_single(dev, *phys, size, size, dir,
 			attrs | DMA_ATTR_SKIP_CPU_SYNC);
 		return false;
-- 
2.20.1


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

* Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions
  2019-11-19 16:46         ` Christoph Hellwig
@ 2019-11-20  6:31           ` Marek Szyprowski
  0 siblings, 0 replies; 14+ messages in thread
From: Marek Szyprowski @ 2019-11-20  6:31 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Krzysztof Kozlowski, Nicolas Saenz Julienne, iommu, Russell King,
	linuxppc-dev, linux-mips, linux-arm-kernel, Linux Samsung SOC,
	Robin Gong, Vinod Koul

Hi

On 19.11.2019 17:46, Christoph Hellwig wrote:
> On Tue, Nov 19, 2019 at 11:26:39AM +0100, Marek Szyprowski wrote:
>> Christoph: Let me know if this is a proper fix for you, then I will send
>> it as a full patch.
> Besides the point from Robin, which is really older than you patch
> I'm not a fan of duplicating dma_capable here.  Let me know what you
> think of the two attached patches.

I'm fine with both patches.

Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

end of thread, other threads:[~2019-11-20  6:32 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-13  7:35 unify the dma_capable definition Christoph Hellwig
2019-11-13  7:35 ` [PATCH 1/3] dma-direct: unify the dma_capable definitions Christoph Hellwig
2019-11-14  8:47   ` Michael Ellerman
2019-11-19  9:27   ` Marek Szyprowski
2019-11-19  9:44     ` Krzysztof Kozlowski
2019-11-19 10:26       ` Marek Szyprowski
2019-11-19 16:16         ` Robin Murphy
2019-11-19 16:46         ` Christoph Hellwig
2019-11-20  6:31           ` Marek Szyprowski
2019-11-19 10:19     ` Nicolas Saenz Julienne
2019-11-13  7:35 ` [PATCH 2/3] dma-direct: avoid a forward declaration for phys_to_dma Christoph Hellwig
2019-11-13  7:35 ` [PATCH 3/3] powerpc: remove support for NULL dev in __phys_to_dma / __dma_to_phys Christoph Hellwig
2019-11-14  8:48   ` Michael Ellerman
2019-11-13 10:18 ` unify the dma_capable definition Nicolas Saenz Julienne

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).