diff options
Diffstat (limited to 'dma-stop-losing-firmware-set-dma-masks.patch')
-rw-r--r-- | dma-stop-losing-firmware-set-dma-masks.patch | 434 |
1 files changed, 0 insertions, 434 deletions
diff --git a/dma-stop-losing-firmware-set-dma-masks.patch b/dma-stop-losing-firmware-set-dma-masks.patch deleted file mode 100644 index 966434e7e..000000000 --- a/dma-stop-losing-firmware-set-dma-masks.patch +++ /dev/null @@ -1,434 +0,0 @@ -From a5516219b10218a87abb3352c82248ce3088e94a Mon Sep 17 00:00:00 2001 -From: Robin Murphy <robin.murphy@arm.com> -Date: Fri, 27 Jul 2018 15:14:15 +0100 -Subject: of/platform: Initialise default DMA masks - -When of_dma_configure() was first born in 591c1ee465ce ("of: configure -the platform device dma parameters"), everything DMA-related was -factored out of of_platform_device_create_pdata() as seemed appropriate -at the time. However, now that of_dma_configure() has grown into the -generic handler for processing DMA-related properties from DT for all -kinds of devices, it is no longer an appropriate place to be doing -OF-platform-specific business. Since there are still plenty of platform -drivers not setting their own masks and depending on the bus default, -let's reinstate that inialisation in the OF-platform code itself, and -restore the long-standing status quo from 0589342c2794 ("of: set -dma_mask to point to coherent_dma_mask") - -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/platform.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/of/platform.c b/drivers/of/platform.c -index 6925d993e1f0..7ba90c290a42 100644 ---- a/drivers/of/platform.c -+++ b/drivers/of/platform.c -@@ -185,6 +185,9 @@ static struct platform_device *of_platform_device_create_pdata( - if (!dev) - goto err_clear_flag; - -+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); -+ if (!dev->dev.dma_mask) -+ dev->dev.dma_mask = &dev->dev.coherent_dma_mask; - dev->dev.bus = &platform_bus_type; - dev->dev.platform_data = platform_data; - of_msi_configure(&dev->dev, dev->dev.of_node); --- -cgit 1.2-0.3.lf.el7 -From 5ac65e8c89410892189ef778f567da4adafb2e2f Mon Sep 17 00:00:00 2001 -From: Robin Murphy <robin.murphy@arm.com> -Date: Mon, 23 Jul 2018 23:16:06 +0100 -Subject: ACPI/IORT: Support address size limit for root complexes - -IORT revision D allows PCI root complex nodes to specify a memory -address size limit equivalently to named components, to help describe -straightforward integrations which don't really warrant a full-blown -_DMA method. Now that our headers are up-to-date, plumb it in. - -If both _DMA and an address size limit are present, we would always -expect the former to be a more specific subset of the latter (since it -makes little sense for a _DMA range to involve bits which IORT says -aren't wired up), thus we can save calculating an explicit intersection -of the two effective masks and simply use short-circuit logic instead. - -Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org> -Signed-off-by: Robin Murphy <robin.murphy@arm.com> -Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> -Acked-by: Will Deacon <will.deacon@arm.com> -Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> -Signed-off-by: Christoph Hellwig <hch@lst.de> ---- - drivers/acpi/arm64/iort.c | 25 +++++++++++++++++++++++-- - 1 file changed, 23 insertions(+), 2 deletions(-) - -diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c -index 7a3a541046ed..4a66896e2aa3 100644 ---- a/drivers/acpi/arm64/iort.c -+++ b/drivers/acpi/arm64/iort.c -@@ -947,6 +947,24 @@ static int nc_dma_get_range(struct device *dev, u64 *size) - return 0; - } - -+static int rc_dma_get_range(struct device *dev, u64 *size) -+{ -+ struct acpi_iort_node *node; -+ struct acpi_iort_root_complex *rc; -+ -+ node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, -+ iort_match_node_callback, dev); -+ if (!node || node->revision < 1) -+ return -ENODEV; -+ -+ rc = (struct acpi_iort_root_complex *)node->node_data; -+ -+ *size = rc->memory_address_limit >= 64 ? U64_MAX : -+ 1ULL<<rc->memory_address_limit; -+ -+ return 0; -+} -+ - /** - * iort_dma_setup() - Set-up device DMA parameters. - * -@@ -975,10 +993,13 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) - - size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); - -- if (dev_is_pci(dev)) -+ if (dev_is_pci(dev)) { - ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size); -- else -+ if (ret == -ENODEV) -+ ret = rc_dma_get_range(dev, &size); -+ } else { - ret = nc_dma_get_range(dev, &size); -+ } - - if (!ret) { - msb = fls64(dmaaddr + size - 1); --- -cgit 1.2-0.3.lf.el7 -From f07d141fe9430cdf9f8a65a87c4136bd83b8ab2e Mon Sep 17 00:00:00 2001 -From: Robin Murphy <robin.murphy@arm.com> -Date: Mon, 23 Jul 2018 23:16:07 +0100 -Subject: dma-mapping: Generalise dma_32bit_limit flag - -Whilst the notion of an upstream DMA restriction is most commonly seen -in PCI host bridges saddled with a 32-bit native interface, a more -general version of the same issue can exist on complex SoCs where a bus -or point-to-point interconnect link from a device's DMA master interface -to another component along the path to memory (often an IOMMU) may carry -fewer address bits than the interfaces at both ends nominally support. -In order to properly deal with this, the first step is to expand the -dma_32bit_limit flag into an arbitrary mask. - -To minimise the impact on existing code, we'll make sure to only -consider this new mask valid if set. That makes sense anyway, since a -mask of zero would represent DMA not being wired up at all, and that -would be better handled by not providing valid ops in the first place. - -Signed-off-by: Robin Murphy <robin.murphy@arm.com> -Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> -Signed-off-by: Christoph Hellwig <hch@lst.de> ---- - arch/x86/kernel/pci-dma.c | 2 +- - include/linux/device.h | 6 +++--- - kernel/dma/direct.c | 6 +++--- - 3 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c -index ab5d9dd668d2..80f9fe8d27d0 100644 ---- a/arch/x86/kernel/pci-dma.c -+++ b/arch/x86/kernel/pci-dma.c -@@ -175,7 +175,7 @@ rootfs_initcall(pci_iommu_init); - - static int via_no_dac_cb(struct pci_dev *pdev, void *data) - { -- pdev->dev.dma_32bit_limit = true; -+ pdev->dev.bus_dma_mask = DMA_BIT_MASK(32); - return 0; - } - -diff --git a/include/linux/device.h b/include/linux/device.h -index 055a69dbcd18..6d3b000be57e 100644 ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -886,6 +886,8 @@ struct dev_links_info { - * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all - * hardware supports 64-bit addresses for consistent allocations - * such descriptors. -+ * @bus_dma_mask: Mask of an upstream bridge or bus which imposes a smaller DMA -+ * limit than the device itself supports. - * @dma_pfn_offset: offset of DMA memory range relatively of RAM - * @dma_parms: A low level driver may set these to teach IOMMU code about - * segment limitations. -@@ -912,8 +914,6 @@ struct dev_links_info { - * @offline: Set after successful invocation of bus type's .offline(). - * @of_node_reused: Set if the device-tree node is shared with an ancestor - * device. -- * @dma_32bit_limit: bridge limited to 32bit DMA even if the device itself -- * indicates support for a higher limit in the dma_mask field. - * - * At the lowest level, every device in a Linux system is represented by an - * instance of struct device. The device structure contains the information -@@ -967,6 +967,7 @@ struct device { - not all hardware supports - 64 bit addresses for consistent - allocations such descriptors. */ -+ u64 bus_dma_mask; /* upstream dma_mask constraint */ - unsigned long dma_pfn_offset; - - struct device_dma_parameters *dma_parms; -@@ -1002,7 +1003,6 @@ struct device { - bool offline_disabled:1; - bool offline:1; - bool of_node_reused:1; -- bool dma_32bit_limit:1; - }; - - static inline struct device *kobj_to_dev(struct kobject *kobj) -diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c -index 8be8106270c2..c2860c5a9e96 100644 ---- a/kernel/dma/direct.c -+++ b/kernel/dma/direct.c -@@ -180,10 +180,10 @@ int dma_direct_supported(struct device *dev, u64 mask) - return 0; - #endif - /* -- * Various PCI/PCIe bridges have broken support for > 32bit DMA even -- * if the device itself might support it. -+ * Upstream PCI/PCIe bridges or SoC interconnects may not carry -+ * as many DMA address bits as the device itself supports. - */ -- if (dev->dma_32bit_limit && mask > DMA_BIT_MASK(32)) -+ if (dev->bus_dma_mask && mask > dev->bus_dma_mask) - return 0; - return 1; - } --- -cgit 1.2-0.3.lf.el7 -From d74ea7100b0d065f2008c4e1ddf637483bc3d28c Mon Sep 17 00:00:00 2001 -From: Robin Murphy <robin.murphy@arm.com> -Date: Mon, 23 Jul 2018 23:16:08 +0100 -Subject: ACPI/IORT: Set bus DMA mask as appropriate - -When an explicit DMA limit is described by firmware, we need to remember -it regardless of how drivers might subsequently update their devices' -masks. The new bus_dma_mask field does that. - -Signed-off-by: Robin Murphy <robin.murphy@arm.com> -Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> -Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> -Signed-off-by: Christoph Hellwig <hch@lst.de> ---- - drivers/acpi/arm64/iort.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c -index 4a66896e2aa3..bc51cff5505e 100644 ---- a/drivers/acpi/arm64/iort.c -+++ b/drivers/acpi/arm64/iort.c -@@ -1014,6 +1014,7 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) - * Limit coherent and dma mask based on size - * retrieved from firmware. - */ -+ dev->bus_dma_mask = mask; - dev->coherent_dma_mask = mask; - *dev->dma_mask = mask; - } --- -cgit 1.2-0.3.lf.el7 -From 6c2fb2ea76361da9b420a8e23a2a19e7842cbdda Mon Sep 17 00:00:00 2001 -From: Robin Murphy <robin.murphy@arm.com> -Date: Mon, 23 Jul 2018 23:16:09 +0100 -Subject: of/device: Set bus DMA mask as appropriate - -When an explicit DMA limit is described by firmware, we need to remember -it regardless of how drivers might subsequently update their devices' -masks. The new bus_dma_mask field does that. - -Signed-off-by: Robin Murphy <robin.murphy@arm.com> -Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> -Signed-off-by: Christoph Hellwig <hch@lst.de> ---- - drivers/of/device.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/of/device.c b/drivers/of/device.c -index 33d85511d790..0d39633e8545 100644 ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -149,6 +149,7 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma) - * set by the driver. - */ - mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1); -+ dev->bus_dma_mask = mask; - dev->coherent_dma_mask &= mask; - *dev->dma_mask &= mask; - --- -cgit 1.2-0.3.lf.el7 -From 03bfdc31176cbe21e456f889ccbbf67568831149 Mon Sep 17 00:00:00 2001 -From: Robin Murphy <robin.murphy@arm.com> -Date: Mon, 23 Jul 2018 23:16:10 +0100 -Subject: iommu/dma: Respect bus DMA limit for IOVAs - -Take the new bus limit into account (when present) for IOVA allocations, -to accommodate those SoCs which integrate off-the-shelf IP blocks with -narrower interconnects such that the link between a device output and an -IOMMU input can truncate DMA addresses to even fewer bits than the -native size of either block's interface would imply. - -Eventually it might make sense for the DMA core to apply this constraint -up-front in dma_set_mask() and friends, but for now this seems like the -least risky approach. - -Signed-off-by: Robin Murphy <robin.murphy@arm.com> -Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> -Acked-by: Joerg Roedel <jroedel@suse.de> -Signed-off-by: Christoph Hellwig <hch@lst.de> ---- - drivers/iommu/dma-iommu.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c -index ddcbbdb5d658..511ff9a1d6d9 100644 ---- a/drivers/iommu/dma-iommu.c -+++ b/drivers/iommu/dma-iommu.c -@@ -367,6 +367,9 @@ static dma_addr_t iommu_dma_alloc_iova(struct iommu_domain *domain, - if (iova_len < (1 << (IOVA_RANGE_CACHE_MAX_SIZE - 1))) - iova_len = roundup_pow_of_two(iova_len); - -+ if (dev->bus_dma_mask) -+ dma_limit &= dev->bus_dma_mask; -+ - if (domain->geometry.force_aperture) - dma_limit = min(dma_limit, domain->geometry.aperture_end); - --- -cgit 1.2-0.3.lf.el7 -From 6757cdae44449dec2af68cd4db0a5f9a30e66b38 Mon Sep 17 00:00:00 2001 -From: Robin Murphy <robin.murphy@arm.com> -Date: Mon, 23 Jul 2018 23:16:11 +0100 -Subject: ACPI/IORT: Don't set default coherent DMA mask - -Now that we can track upstream DMA constraints properly with -bus_dma_mask instead of trying (and failing) to maintain it in -coherent_dma_mask, it doesn't make much sense for the firmware code to -be touching the latter at all. It's merely papering over bugs wherein a -driver has failed to call dma_set_coherent_mask() *and* the bus code has -not initialised any default value. - -We don't really want to encourage more drivers coercing dma_mask so -we'll continue to fix that up if necessary, but add a warning to help -flush out any such buggy bus code that remains. - -Signed-off-by: Robin Murphy <robin.murphy@arm.com> -Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> -Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> -Signed-off-by: Christoph Hellwig <hch@lst.de> ---- - drivers/acpi/arm64/iort.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c -index bc51cff5505e..08f26db2da7e 100644 ---- a/drivers/acpi/arm64/iort.c -+++ b/drivers/acpi/arm64/iort.c -@@ -978,20 +978,20 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) - int ret, msb; - - /* -- * Set default coherent_dma_mask to 32 bit. Drivers are expected to -- * setup the correct supported mask. -+ * If @dev is expected to be DMA-capable then the bus code that created -+ * it should have initialised its dma_mask pointer by this point. For -+ * now, we'll continue the legacy behaviour of coercing it to the -+ * coherent mask if not, but we'll no longer do so quietly. - */ -- 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) -+ if (!dev->dma_mask) { -+ dev_warn(dev, "DMA mask not set\n"); - dev->dma_mask = &dev->coherent_dma_mask; -+ } - -- size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); -+ if (dev->coherent_dma_mask) -+ size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); -+ else -+ size = 1ULL << 32; - - if (dev_is_pci(dev)) { - ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size); --- -cgit 1.2-0.3.lf.el7 -From 4d8bde883bfba3e8dd3335f91b640e5a70ec0aa6 Mon Sep 17 00:00:00 2001 -From: Robin Murphy <robin.murphy@arm.com> -Date: Mon, 23 Jul 2018 23:16:12 +0100 -Subject: OF: Don't set default coherent DMA mask - -Now that we can track upstream DMA constraints properly with -bus_dma_mask instead of trying (and failing) to maintain it in -coherent_dma_mask, it doesn't make much sense for the firmware code to -be touching the latter at all. It's merely papering over bugs wherein a -driver has failed to call dma_set_coherent_mask() *and* the bus code has -not initialised any default value. - -We don't really want to encourage more drivers coercing dma_mask so -we'll continue to fix that up if necessary, but add a warning to help -flush out any such buggy bus code that remains. - -Signed-off-by: Robin Murphy <robin.murphy@arm.com> -Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> -Signed-off-by: Christoph Hellwig <hch@lst.de> ---- - drivers/of/device.c | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - -diff --git a/drivers/of/device.c b/drivers/of/device.c -index 0d39633e8545..5957cd4fa262 100644 ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -127,20 +127,20 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma) - } - - /* -- * Set default coherent_dma_mask to 32 bit. Drivers are expected to -- * setup the correct supported mask. -+ * If @dev is expected to be DMA-capable then the bus code that created -+ * it should have initialised its dma_mask pointer by this point. For -+ * now, we'll continue the legacy behaviour of coercing it to the -+ * coherent mask if not, but we'll no longer do so quietly. - */ -- 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) -+ if (!dev->dma_mask) { -+ dev_warn(dev, "DMA mask not set\n"); - dev->dma_mask = &dev->coherent_dma_mask; -+ } - -- if (!size) -+ if (!size && dev->coherent_dma_mask) - size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); -+ else if (!size) -+ size = 1ULL << 32; - - dev->dma_pfn_offset = offset; - --- -cgit 1.2-0.3.lf.el7 |