All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
To: Arnd Bergmann <arnd@arndb.de>
Cc: linux-arm-kernel@lists.infradead.org,
	Will Deacon <will.deacon@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	Simon Horman <horms@verge.net.au>,
	Bjorn Helgaas <bhelgaas@google.com>,
	artemi.ivanov@cogentembedded.com,
	Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Subject: [PATCH] arm64: do not set dma masks that device connection can't handle
Date: Fri,  6 Jan 2017 17:45:11 +0300	[thread overview]
Message-ID: <1483713911-2079-1-git-send-email-nikita.yoush@cogentembedded.com> (raw)
In-Reply-To: <9a03c05d-ad4c-0547-d1fe-01edb8b082d6@cogentembedded.com>

It is possible that device is capable of 64-bit DMA addresses, and
device driver tries to set wide DMA mask, but bridge or bus used to
connect device to the system can't handle wide addresses.

With swiotlb, memory above 4G still can be used by drivers for streaming
DMA, but *dev->mask and dev->dma_coherent_mask must still keep values
that hardware handles physically.

This patch enforces that. Based on original version by
Arnd Bergmann <arnd@arndb.de>, extended with coherent mask hadnling.

Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
CC: Arnd Bergmann <arnd@arndb.de>
---

... now with initially missed change in arch_setup_dma_ops() ...

 arch/arm64/Kconfig              |  3 +++
 arch/arm64/include/asm/device.h |  1 +
 arch/arm64/mm/dma-mapping.c     | 52 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1117421..afb2c08 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -216,6 +216,9 @@ config NEED_DMA_MAP_STATE
 config NEED_SG_DMA_LENGTH
 	def_bool y
 
+config ARCH_HAS_DMA_SET_COHERENT_MASK
+	def_bool y
+
 config SMP
 	def_bool y
 
diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h
index 243ef25..a57e7bb 100644
--- a/arch/arm64/include/asm/device.h
+++ b/arch/arm64/include/asm/device.h
@@ -22,6 +22,7 @@ struct dev_archdata {
 	void *iommu;			/* private IOMMU data */
 #endif
 	bool dma_coherent;
+	u64 parent_dma_mask;
 };
 
 struct pdev_archdata {
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 290a84f..09c7900 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -352,6 +352,31 @@ static int __swiotlb_dma_supported(struct device *hwdev, u64 mask)
 	return 1;
 }
 
+static int __swiotlb_set_dma_mask(struct device *dev, u64 mask)
+{
+	/* device is not DMA capable */
+	if (!dev->dma_mask)
+		return -EIO;
+
+	/* mask is below swiotlb bounce buffer, so fail */
+	if (!swiotlb_dma_supported(dev, mask))
+		return -EIO;
+
+	/*
+	 * because of the swiotlb, we can return success for
+	 * larger masks, but need to ensure that bounce buffers
+	 * are used above parent_dma_mask, so set that as
+	 * the effective mask.
+	 */
+	if (mask > dev->archdata.parent_dma_mask)
+		mask = dev->archdata.parent_dma_mask;
+
+
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
 static struct dma_map_ops swiotlb_dma_ops = {
 	.alloc = __dma_alloc,
 	.free = __dma_free,
@@ -367,8 +392,23 @@ static struct dma_map_ops swiotlb_dma_ops = {
 	.sync_sg_for_device = __swiotlb_sync_sg_for_device,
 	.dma_supported = __swiotlb_dma_supported,
 	.mapping_error = swiotlb_dma_mapping_error,
+	.set_dma_mask = __swiotlb_set_dma_mask,
 };
 
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+	if (!dma_supported(dev, mask))
+		return -EIO;
+
+	if (get_dma_ops(dev) == &swiotlb_dma_ops &&
+	    mask > dev->archdata.parent_dma_mask)
+		mask = dev->archdata.parent_dma_mask;
+
+	dev->coherent_dma_mask = mask;
+	return 0;
+}
+EXPORT_SYMBOL(dma_set_coherent_mask);
+
 static int __init atomic_pool_init(void)
 {
 	pgprot_t prot = __pgprot(PROT_NORMAL_NC);
@@ -957,6 +997,18 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 	if (!dev->archdata.dma_ops)
 		dev->archdata.dma_ops = &swiotlb_dma_ops;
 
+	/*
+	 * we don't yet support buses that have a non-zero mapping.
+	 *  Let's hope we won't need it
+	 */
+	WARN_ON(dma_base != 0);
+
+	/*
+	 * Whatever the parent bus can set. A device must not set
+	 * a DMA mask larger than this.
+	 */
+	dev->archdata.parent_dma_mask = size;
+
 	dev->archdata.dma_coherent = coherent;
 	__iommu_setup_dma_ops(dev, dma_base, size, iommu);
 }
-- 
2.1.4

WARNING: multiple messages have this Message-ID (diff)
From: nikita.yoush@cogentembedded.com (Nikita Yushchenko)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] arm64: do not set dma masks that device connection can't handle
Date: Fri,  6 Jan 2017 17:45:11 +0300	[thread overview]
Message-ID: <1483713911-2079-1-git-send-email-nikita.yoush@cogentembedded.com> (raw)
In-Reply-To: <9a03c05d-ad4c-0547-d1fe-01edb8b082d6@cogentembedded.com>

It is possible that device is capable of 64-bit DMA addresses, and
device driver tries to set wide DMA mask, but bridge or bus used to
connect device to the system can't handle wide addresses.

With swiotlb, memory above 4G still can be used by drivers for streaming
DMA, but *dev->mask and dev->dma_coherent_mask must still keep values
that hardware handles physically.

This patch enforces that. Based on original version by
Arnd Bergmann <arnd@arndb.de>, extended with coherent mask hadnling.

Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
CC: Arnd Bergmann <arnd@arndb.de>
---

... now with initially missed change in arch_setup_dma_ops() ...

 arch/arm64/Kconfig              |  3 +++
 arch/arm64/include/asm/device.h |  1 +
 arch/arm64/mm/dma-mapping.c     | 52 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1117421..afb2c08 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -216,6 +216,9 @@ config NEED_DMA_MAP_STATE
 config NEED_SG_DMA_LENGTH
 	def_bool y
 
+config ARCH_HAS_DMA_SET_COHERENT_MASK
+	def_bool y
+
 config SMP
 	def_bool y
 
diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h
index 243ef25..a57e7bb 100644
--- a/arch/arm64/include/asm/device.h
+++ b/arch/arm64/include/asm/device.h
@@ -22,6 +22,7 @@ struct dev_archdata {
 	void *iommu;			/* private IOMMU data */
 #endif
 	bool dma_coherent;
+	u64 parent_dma_mask;
 };
 
 struct pdev_archdata {
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 290a84f..09c7900 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -352,6 +352,31 @@ static int __swiotlb_dma_supported(struct device *hwdev, u64 mask)
 	return 1;
 }
 
+static int __swiotlb_set_dma_mask(struct device *dev, u64 mask)
+{
+	/* device is not DMA capable */
+	if (!dev->dma_mask)
+		return -EIO;
+
+	/* mask is below swiotlb bounce buffer, so fail */
+	if (!swiotlb_dma_supported(dev, mask))
+		return -EIO;
+
+	/*
+	 * because of the swiotlb, we can return success for
+	 * larger masks, but need to ensure that bounce buffers
+	 * are used above parent_dma_mask, so set that as
+	 * the effective mask.
+	 */
+	if (mask > dev->archdata.parent_dma_mask)
+		mask = dev->archdata.parent_dma_mask;
+
+
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
 static struct dma_map_ops swiotlb_dma_ops = {
 	.alloc = __dma_alloc,
 	.free = __dma_free,
@@ -367,8 +392,23 @@ static struct dma_map_ops swiotlb_dma_ops = {
 	.sync_sg_for_device = __swiotlb_sync_sg_for_device,
 	.dma_supported = __swiotlb_dma_supported,
 	.mapping_error = swiotlb_dma_mapping_error,
+	.set_dma_mask = __swiotlb_set_dma_mask,
 };
 
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+	if (!dma_supported(dev, mask))
+		return -EIO;
+
+	if (get_dma_ops(dev) == &swiotlb_dma_ops &&
+	    mask > dev->archdata.parent_dma_mask)
+		mask = dev->archdata.parent_dma_mask;
+
+	dev->coherent_dma_mask = mask;
+	return 0;
+}
+EXPORT_SYMBOL(dma_set_coherent_mask);
+
 static int __init atomic_pool_init(void)
 {
 	pgprot_t prot = __pgprot(PROT_NORMAL_NC);
@@ -957,6 +997,18 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 	if (!dev->archdata.dma_ops)
 		dev->archdata.dma_ops = &swiotlb_dma_ops;
 
+	/*
+	 * we don't yet support buses that have a non-zero mapping.
+	 *  Let's hope we won't need it
+	 */
+	WARN_ON(dma_base != 0);
+
+	/*
+	 * Whatever the parent bus can set. A device must not set
+	 * a DMA mask larger than this.
+	 */
+	dev->archdata.parent_dma_mask = size;
+
 	dev->archdata.dma_coherent = coherent;
 	__iommu_setup_dma_ops(dev, dma_base, size, iommu);
 }
-- 
2.1.4

  parent reply	other threads:[~2017-01-06 14:50 UTC|newest]

Thread overview: 115+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-29 20:45 [PATCH 1/2] arm64: dma_mapping: allow PCI host driver to limit DMA mask Nikita Yushchenko
2016-12-29 20:45 ` Nikita Yushchenko
2016-12-29 20:45 ` [PATCH 2/2] rcar-pcie: set host bridge's " Nikita Yushchenko
2016-12-29 20:45   ` Nikita Yushchenko
2016-12-29 21:18 ` [PATCH 1/2] arm64: dma_mapping: allow PCI host driver to limit " Arnd Bergmann
2017-02-16 16:12   ` Arnd Bergmann
2016-12-29 21:18   ` Arnd Bergmann
2016-12-30  9:46 ` Sergei Shtylyov
2016-12-30  9:46   ` Sergei Shtylyov
2016-12-30 10:06   ` Sergei Shtylyov
2016-12-30 10:06     ` Sergei Shtylyov
2017-01-03 18:44 ` Will Deacon
2017-01-03 18:44   ` Will Deacon
2017-01-03 19:00   ` Nikita Yushchenko
2017-01-03 19:00     ` Nikita Yushchenko
2017-01-03 19:01   ` Nikita Yushchenko
2017-01-03 19:01     ` Nikita Yushchenko
2017-01-03 19:01     ` Nikita Yushchenko
2017-01-03 20:13     ` Grygorii Strashko
2017-01-03 20:13       ` Grygorii Strashko
2017-01-03 20:13       ` Grygorii Strashko
2017-01-03 20:23       ` Nikita Yushchenko
2017-01-03 20:23         ` Nikita Yushchenko
2017-01-03 20:23         ` Nikita Yushchenko
2017-01-03 23:13   ` Arnd Bergmann
2017-01-03 23:13     ` Arnd Bergmann
2017-01-03 23:13     ` Arnd Bergmann
2017-01-04  6:24     ` Nikita Yushchenko
2017-01-04  6:24       ` Nikita Yushchenko
2017-01-04  6:24       ` Nikita Yushchenko
2017-01-04 13:29       ` Arnd Bergmann
2017-01-04 13:29         ` Arnd Bergmann
2017-01-04 13:29         ` Arnd Bergmann
2017-01-04 14:30         ` Nikita Yushchenko
2017-01-04 14:30           ` Nikita Yushchenko
2017-01-04 14:30           ` Nikita Yushchenko
2017-01-04 14:46           ` Arnd Bergmann
2017-01-04 14:46             ` Arnd Bergmann
2017-01-04 15:29             ` Nikita Yushchenko
2017-01-04 15:29               ` Nikita Yushchenko
2017-01-04 15:29               ` Nikita Yushchenko
2017-01-06 11:10               ` Arnd Bergmann
2017-01-06 11:10                 ` Arnd Bergmann
2017-01-06 11:10                 ` Arnd Bergmann
2017-01-06 13:47                 ` Nikita Yushchenko
2017-01-06 13:47                   ` Nikita Yushchenko
2017-01-06 13:47                   ` Nikita Yushchenko
2017-01-06 14:38                   ` [PATCH] arm64: do not set dma masks that device connection can't handle Nikita Yushchenko
2017-01-06 14:38                     ` Nikita Yushchenko
2017-01-06 14:45                   ` Nikita Yushchenko [this message]
2017-01-06 14:45                     ` Nikita Yushchenko
2017-01-08  7:09                     ` Sergei Shtylyov
2017-01-08  7:09                       ` Sergei Shtylyov
2017-01-09  6:56                       ` Nikita Yushchenko
2017-01-09  6:56                         ` Nikita Yushchenko
2017-01-09 14:05                   ` [PATCH 1/2] arm64: dma_mapping: allow PCI host driver to limit DMA mask Arnd Bergmann
2017-01-09 14:05                     ` Arnd Bergmann
2017-01-09 14:05                     ` Arnd Bergmann
2017-01-09 20:34                     ` Nikita Yushchenko
2017-01-09 20:34                       ` Nikita Yushchenko
2017-01-09 20:34                       ` Nikita Yushchenko
2017-01-09 20:34                       ` Nikita Yushchenko
2017-01-09 20:57                       ` Christoph Hellwig
2017-01-09 20:57                         ` Christoph Hellwig
2017-01-09 20:57                         ` Christoph Hellwig
2017-01-09 20:57                         ` Christoph Hellwig
2017-01-10  6:47                         ` NVMe vs DMA addressing limitations Nikita Yushchenko
2017-01-10  7:07                           ` Christoph Hellwig
2017-01-10  7:07                             ` Christoph Hellwig
2017-01-10  7:07                             ` Christoph Hellwig
2017-01-10  7:07                             ` Christoph Hellwig
2017-01-10  7:31                             ` Nikita Yushchenko
2017-01-10  7:31                               ` Nikita Yushchenko
2017-01-10  7:31                               ` Nikita Yushchenko
2017-01-10  7:31                               ` Nikita Yushchenko
2017-01-10 11:01                               ` Arnd Bergmann
2017-01-10 11:01                                 ` Arnd Bergmann
2017-01-10 11:01                                 ` Arnd Bergmann
2017-01-10 11:01                                 ` Arnd Bergmann
2017-01-10 14:48                                 ` Christoph Hellwig
2017-01-10 14:48                                   ` Christoph Hellwig
2017-01-10 14:48                                   ` Christoph Hellwig
2017-01-10 14:48                                   ` Christoph Hellwig
2017-01-10 15:02                                   ` Arnd Bergmann
2017-01-10 15:02                                     ` Arnd Bergmann
2017-01-10 15:02                                     ` Arnd Bergmann
2017-01-10 15:02                                     ` Arnd Bergmann
2017-01-12 10:09                                   ` Sagi Grimberg
2017-01-12 10:09                                     ` Sagi Grimberg
2017-01-12 10:09                                     ` Sagi Grimberg
2017-01-12 10:09                                     ` Sagi Grimberg
2017-01-12 11:56                                     ` Arnd Bergmann
2017-01-12 11:56                                       ` Arnd Bergmann
2017-01-12 11:56                                       ` Arnd Bergmann
2017-01-12 11:56                                       ` Arnd Bergmann
2017-01-12 13:07                                       ` Christoph Hellwig
2017-01-12 13:07                                         ` Christoph Hellwig
2017-01-12 13:07                                         ` Christoph Hellwig
2017-01-12 13:07                                         ` Christoph Hellwig
2017-01-10 10:54                             ` Arnd Bergmann
2017-01-10 10:54                               ` Arnd Bergmann
2017-01-10 10:54                               ` Arnd Bergmann
2017-01-10 10:54                               ` Arnd Bergmann
2017-01-10 10:47                         ` [PATCH 1/2] arm64: dma_mapping: allow PCI host driver to limit DMA mask Arnd Bergmann
2017-01-10 10:47                           ` Arnd Bergmann
2017-01-10 10:47                           ` Arnd Bergmann
2017-01-10 10:47                           ` Arnd Bergmann
2017-01-10 14:44                           ` Christoph Hellwig
2017-01-10 14:44                             ` Christoph Hellwig
2017-01-10 14:44                             ` Christoph Hellwig
2017-01-10 14:44                             ` Christoph Hellwig
2017-01-10 15:00                             ` Arnd Bergmann
2017-01-10 15:00                               ` Arnd Bergmann
2017-01-10 15:00                               ` Arnd Bergmann
2017-01-10 15:00                               ` Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1483713911-2079-1-git-send-email-nikita.yoush@cogentembedded.com \
    --to=nikita.yoush@cogentembedded.com \
    --cc=arnd@arndb.de \
    --cc=artemi.ivanov@cogentembedded.com \
    --cc=bhelgaas@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=horms@verge.net.au \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.