Fix issue with DMA allocation with some device configurations
This commit is contained in:
parent
77bac469cf
commit
eecd41d126
|
@ -0,0 +1,121 @@
|
|||
From 723288836628bc1c0855f3bb7b64b1803e4b9e4a Mon Sep 17 00:00:00 2001
|
||||
From: Robin Murphy <robin.murphy@arm.com>
|
||||
Date: Thu, 31 Aug 2017 11:32:54 +0100
|
||||
Subject: of: restrict DMA configuration
|
||||
|
||||
Moving DMA configuration to happen later at driver probe time had the
|
||||
unnoticed side-effect that we now perform DMA configuration for *every*
|
||||
device represented in DT, rather than only those explicitly created by
|
||||
the of_platform and PCI code.
|
||||
|
||||
As Christoph points out, this is not really the best thing to do. Whilst
|
||||
there may well be other DMA-capable buses that can benefit from having
|
||||
their children automatically configured after the bridge has probed,
|
||||
there are also plenty of others like USB, MDIO, etc. that definitely do
|
||||
not support DMA and should not be indiscriminately processed.
|
||||
|
||||
The good news is that in most cases the DT "dma-ranges" property serves
|
||||
as an appropriate indicator - per a strict interpretation of the spec,
|
||||
anything lacking a "dma-ranges" property should be considered not to
|
||||
have a mapping of DMA address space from its children to its parent,
|
||||
thus anything for which of_dma_get_range() does not succeed does not
|
||||
need DMA configuration. Certain bus types have a general expectation of
|
||||
DMA capability and carry a well-established precedent that an absent
|
||||
"dma-ranges" implies the same as the empty property, so we automatically
|
||||
opt those in to DMA configuration regardless, to avoid regressing most
|
||||
existing platforms.
|
||||
|
||||
Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices")
|
||||
Reported-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
||||
---
|
||||
drivers/of/device.c | 48 ++++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 32 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/drivers/of/device.c b/drivers/of/device.c
|
||||
index e0a28ea..04c4c95 100644
|
||||
--- a/drivers/of/device.c
|
||||
+++ b/drivers/of/device.c
|
||||
@@ -9,6 +9,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/amba/bus.h>
|
||||
|
||||
#include <asm/errno.h>
|
||||
#include "of_private.h"
|
||||
@@ -84,31 +87,28 @@ int of_device_add(struct platform_device *ofdev)
|
||||
*/
|
||||
int of_dma_configure(struct device *dev, struct device_node *np)
|
||||
{
|
||||
- u64 dma_addr, paddr, size;
|
||||
+ u64 dma_addr, paddr, size = 0;
|
||||
int ret;
|
||||
bool coherent;
|
||||
unsigned long offset;
|
||||
const struct iommu_ops *iommu;
|
||||
u64 mask;
|
||||
|
||||
- /*
|
||||
- * Set default coherent_dma_mask to 32 bit. Drivers are expected to
|
||||
- * setup the correct supported mask.
|
||||
- */
|
||||
- if (!dev->coherent_dma_mask)
|
||||
- dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
-
|
||||
- /*
|
||||
- * Set it to coherent_dma_mask by default if the architecture
|
||||
- * code has not set it.
|
||||
- */
|
||||
- if (!dev->dma_mask)
|
||||
- dev->dma_mask = &dev->coherent_dma_mask;
|
||||
-
|
||||
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
|
||||
if (ret < 0) {
|
||||
+ /*
|
||||
+ * For legacy reasons, we have to assume some devices need
|
||||
+ * DMA configuration regardless of whether "dma-ranges" is
|
||||
+ * correctly specified or not.
|
||||
+ */
|
||||
+ if (!dev_is_pci(dev) &&
|
||||
+#ifdef CONFIG_ARM_AMBA
|
||||
+ dev->bus != &amba_bustype &&
|
||||
+#endif
|
||||
+ dev->bus != &platform_bus_type)
|
||||
+ return ret == -ENODEV ? 0 : ret;
|
||||
+
|
||||
dma_addr = offset = 0;
|
||||
- size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
|
||||
} else {
|
||||
offset = PFN_DOWN(paddr - dma_addr);
|
||||
|
||||
@@ -129,6 +129,22 @@ int of_dma_configure(struct device *dev, struct device_node *np)
|
||||
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Set default coherent_dma_mask to 32 bit. Drivers are expected to
|
||||
+ * setup the correct supported mask.
|
||||
+ */
|
||||
+ if (!dev->coherent_dma_mask)
|
||||
+ dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
+ /*
|
||||
+ * Set it to coherent_dma_mask by default if the architecture
|
||||
+ * code has not set it.
|
||||
+ */
|
||||
+ if (!dev->dma_mask)
|
||||
+ dev->dma_mask = &dev->coherent_dma_mask;
|
||||
+
|
||||
+ if (!size)
|
||||
+ size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
|
||||
+
|
||||
dev->dma_pfn_offset = offset;
|
||||
|
||||
/*
|
||||
--
|
||||
cgit v1.1
|
||||
|
|
@ -628,6 +628,9 @@ Patch322: bcm2837-move-dt.patch
|
|||
#
|
||||
Patch323: bcm2837-bluetooth-support.patch
|
||||
|
||||
# https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?h=next-20170912&id=723288836628bc1c0855f3bb7b64b1803e4b9e4a
|
||||
Patch324: arm-of-restrict-dma-configuration.patch
|
||||
|
||||
# 400 - IBM (ppc/s390x) patches
|
||||
|
||||
# 500 - Temp fixes/CVEs etc
|
||||
|
@ -2207,6 +2210,9 @@ fi
|
|||
#
|
||||
#
|
||||
%changelog
|
||||
* Tue Sep 12 2017 Peter Robinson <pbrobinson@fedoraproject.org>
|
||||
- Fix issue with DMA allocation with some device configurations
|
||||
|
||||
* Tue Sep 12 2017 Peter Robinson <pbrobinson@fedoraproject.org> 4.13.1-302
|
||||
- Disable debugging options.
|
||||
|
||||
|
|
Loading…
Reference in New Issue