Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Robin Murphy and committed by
Christoph Hellwig
72328883 2fd523c5

+32 -16
+32 -16
drivers/of/device.c
··· 9 #include <linux/module.h> 10 #include <linux/mod_devicetable.h> 11 #include <linux/slab.h> 12 13 #include <asm/errno.h> 14 #include "of_private.h" ··· 87 */ 88 int of_dma_configure(struct device *dev, struct device_node *np) 89 { 90 - u64 dma_addr, paddr, size; 91 int ret; 92 bool coherent; 93 unsigned long offset; 94 const struct iommu_ops *iommu; 95 u64 mask; 96 97 - /* 98 - * Set default coherent_dma_mask to 32 bit. Drivers are expected to 99 - * setup the correct supported mask. 100 - */ 101 - if (!dev->coherent_dma_mask) 102 - dev->coherent_dma_mask = DMA_BIT_MASK(32); 103 - 104 - /* 105 - * Set it to coherent_dma_mask by default if the architecture 106 - * code has not set it. 107 - */ 108 - if (!dev->dma_mask) 109 - dev->dma_mask = &dev->coherent_dma_mask; 110 - 111 ret = of_dma_get_range(np, &dma_addr, &paddr, &size); 112 if (ret < 0) { 113 dma_addr = offset = 0; 114 - size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); 115 } else { 116 offset = PFN_DOWN(paddr - dma_addr); 117 ··· 128 } 129 dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset); 130 } 131 132 dev->dma_pfn_offset = offset; 133
··· 9 #include <linux/module.h> 10 #include <linux/mod_devicetable.h> 11 #include <linux/slab.h> 12 + #include <linux/pci.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/amba/bus.h> 15 16 #include <asm/errno.h> 17 #include "of_private.h" ··· 84 */ 85 int of_dma_configure(struct device *dev, struct device_node *np) 86 { 87 + u64 dma_addr, paddr, size = 0; 88 int ret; 89 bool coherent; 90 unsigned long offset; 91 const struct iommu_ops *iommu; 92 u64 mask; 93 94 ret = of_dma_get_range(np, &dma_addr, &paddr, &size); 95 if (ret < 0) { 96 + /* 97 + * For legacy reasons, we have to assume some devices need 98 + * DMA configuration regardless of whether "dma-ranges" is 99 + * correctly specified or not. 100 + */ 101 + if (!dev_is_pci(dev) && 102 + #ifdef CONFIG_ARM_AMBA 103 + dev->bus != &amba_bustype && 104 + #endif 105 + dev->bus != &platform_bus_type) 106 + return ret == -ENODEV ? 0 : ret; 107 + 108 dma_addr = offset = 0; 109 } else { 110 offset = PFN_DOWN(paddr - dma_addr); 111 ··· 128 } 129 dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset); 130 } 131 + 132 + /* 133 + * Set default coherent_dma_mask to 32 bit. Drivers are expected to 134 + * setup the correct supported mask. 135 + */ 136 + if (!dev->coherent_dma_mask) 137 + dev->coherent_dma_mask = DMA_BIT_MASK(32); 138 + /* 139 + * Set it to coherent_dma_mask by default if the architecture 140 + * code has not set it. 141 + */ 142 + if (!dev->dma_mask) 143 + dev->dma_mask = &dev->coherent_dma_mask; 144 + 145 + if (!size) 146 + size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); 147 148 dev->dma_pfn_offset = offset; 149