of: Restrict DMA configuration
PATCH v2 1/1 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.
---
v2: Updated commit message to be more reasonable
drivers/of/device.c | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-)
drivers/of/device.c +32 -16
@@ -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;/*
Signature · 1 line
2.13.4.dirty
PATCH v2 1/1 of: Restrict DMA configuration
Thanks Robin. I'll wait for any additional comments until tomorrow and will apply it unless anyone objects.
PATCH v2 1/1 of: Restrict DMA configuration
In reply to Robin MurphyQuoted 25 lines · Robin Murphy
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_platformand 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 <[email protected]>Signed-off-by Robin Murphy <[email protected]>
Quoted 6 lines
---
v2: Updated commit message to be more reasonable
drivers/of/device.c | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-)