drm/nouveau: tegra: Detach from ARM DMA/IOMMU mapping
Subsystems (9)
PATCH v2 1/5 drm/nouveau: tegra: Detach from ARM DMA/IOMMU mapping
From: Thierry Reding <[email protected]>
Depending on the kernel configuration, early ARM architecture setup code may have attached the GPU to a DMA/IOMMU mapping that transparently uses the IOMMU to back the DMA API. Tegra requires special handling for IOMMU backed buffers (a special bit in the GPU's MMU page tables indicates the memory path to take: via the SMMU or directly to the memory controller). Transparently backing DMA memory with an IOMMU prevents Nouveau from properly handling such memory accesses and causes memory access faults.
As a side-note: buffers other than those allocated in instance memory don't need to be physically contiguous from the GPU's perspective since the GPU can map them into contiguous buffers using its own MMU. Mapping these buffers through the IOMMU is unnecessary and will even lead to performance degradation because of the additional translation.
---
I had already sent this out independently to fix a regression that was introduced in v4.16, but then Christoph pointed out that it should've been sent to a wider audience and should use a core API rather than calling into architecture code directly.
I've added it to this series for easier reference and to show the need for the new API.
.../drm/nouveau/nvkm/engine/device/tegra.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +19 -0
@@ -19,6 +19,11 @@* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ + +#if IS_ENABLED (CONFIG_ARM_DMA_USE_IOMMU ) +#include <asm/dma-iommu.h> +#endif +#include <core/tegra.h> #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER #include "priv.h"
@@ -105,6 +110,20 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)unsigned long pgsize_bitmap;int ret; +#if IS_ENABLED (CONFIG_ARM_DMA_USE_IOMMU ) +if (dev->archdata.mapping) { +struct dma_iommu_mapping *mapping =to_dma_iommu_mapping (dev); + +arm_iommu_release_mapping (mapping); +arm_iommu_detach_device (dev); + +if (dev->archdata.dma_coherent) +set_dma_ops (dev, &arm_coherent_dma_ops); +else +set_dma_ops (dev, &arm_dma_ops); + } +#endif +if (!tdev->func->iommu_bit)return ;
Signature · 6 lines
2.17.0 _______________________________________________ Nouveau mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): 20180425101051.15349-1-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
PATCH v2 2/5 dma-mapping: Introduce dma_iommu_detach_device() API
From: Thierry Reding <[email protected]>
The dma_iommu_detach_device() API can be used by drivers to forcibly detach a device from an IOMMU that architecture code might have attached to. This is useful for drivers that need explicit control over the IOMMU using the IOMMU API directly.
--- drivers/base/dma-mapping.c | 8 ++++++++ include/linux/dma-mapping.h | 2 ++ 2 files changed, 10 insertions(+)
drivers/base/dma-mapping.c +8 -0
@@ -366,3 +366,11 @@ void dma_deconfigure(struct device *dev)of_dma_deconfigure (dev);acpi_dma_deconfigure (dev); } + +void dma_iommu_detach_device (struct device *dev) +{ +#ifdef arch_iommu_detach_device +arch_iommu_detach_device (dev); +#endif +} +EXPORT_SYMBOL (dma_iommu_detach_device);
include/linux/dma-mapping.h +2 -0
@@ -671,6 +671,8 @@ static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,static inline void arch_teardown_dma_ops (struct device *dev) { }#endif +extern void dma_iommu_detach_device (struct device *dev); +static inline unsigned int dma_get_max_seg_size (struct device *dev) {if (dev->dma_parms && dev->dma_parms->max_segment_size)
Signature · 1 line
2.17.0
A message that is not in the archive (sent off-list or not yet received): 20180425101051.15349-2-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Re: [PATCH v2 2/5] dma-mapping: Introduce dma_iommu_detach_device() API
Quoted 6 lines · Thierry Reding
From: Thierry Reding <[email protected]>
The
dma_iommu_detach_device()API can be used by drivers to forcibly detach a device from an IOMMU that architecture code might have attached to. This is useful for drivers that need explicit control over the IOMMU using the IOMMU API directly.
Given that no one else implements it making it a generic API seems rather confusing. For now I'd rename it to arm_dma_iommu_detach_device() and only implement it in arm.
Once I've got the dma mapping implementations consolidated to a small enough number we could think about something like a device quirk that tells the architecture to simply never even attach the iommu dma ops to start with.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v2 2/5] dma-mapping: Introduce dma_iommu_detach_device() API
Quoted 11 lines · Christoph Hellwig
Quoted 6 lines · Thierry Reding
From: Thierry Reding <[email protected]>
The
dma_iommu_detach_device()API can be used by drivers to forcibly detach a device from an IOMMU that architecture code might have attached to. This is useful for drivers that need explicit control over the IOMMU using the IOMMU API directly.Given that no one else implements it making it a generic API seems rather confusing. For now I'd rename it to
arm_dma_iommu_detach_device()and only implement it in arm.
That'd be suboptimal because this code is used on both 32-bit and 64-bit ARM. If we make the function 32-bit ARM specific then the driver code would need to use an #ifdef to make sure compilation doesn't break on 64-bit ARM.
Thierry
Re: [PATCH v2 2/5] dma-mapping: Introduce dma_iommu_detach_device() API
Quoted 9 lines · Thierry Reding
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Thierry Reding
From: Thierry Reding <[email protected]>
The
dma_iommu_detach_device()API can be used by drivers to forcibly detach a device from an IOMMU that architecture code might have attached to. This is useful for drivers that need explicit control over the IOMMU using the IOMMU API directly.
Quoted 8 lines
Quoted 3 lines
Given that no one else implements it making it a generic API seems rather confusing. For now I'd rename it to
arm_dma_iommu_detach_device()and only implement it in arm.That'd be suboptimal because this code is used on both 32-bit and 64-bit ARM. If we make the function 32-bit ARM specific then the driver code would need to use an #ifdef to make sure compilation doesn't break on 64-bit ARM.
Do you still want me to make this ARM specific? While I haven't encountered this issue on 64-bit ARM yet, I think it would happen there as well, under the right circumstances. I could take a shot at implementing the equivalent there (which means essentially implementing it for drivers/iommu/dma-iommu.c and calling that from 64-bit ARM code).
Thierry
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Robin Murphy
reviewerRe: [PATCH v2 2/5] dma-mapping: Introduce dma_iommu_detach_device() API
Quoted 19 lines · Thierry Reding
Quoted 9 lines · Thierry Reding
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Thierry Reding
From: Thierry Reding <[email protected]>
The
dma_iommu_detach_device()API can be used by drivers to forcibly detach a device from an IOMMU that architecture code might have attached to. This is useful for drivers that need explicit control over the IOMMU using the IOMMU API directly.Quoted 8 lines
Quoted 3 lines
Given that no one else implements it making it a generic API seems rather confusing. For now I'd rename it to
arm_dma_iommu_detach_device()and only implement it in arm.That'd be suboptimal because this code is used on both 32-bit and 64-bit ARM. If we make the function 32-bit ARM specific then the driver code would need to use an #ifdef to make sure compilation doesn't break on 64-bit ARM.
Quoted 5 lines
Do you still want me to make this ARM specific? While I haven't encountered this issue on 64-bit ARM yet, I think it would happen there as well, under the right circumstances. I could take a shot at implementing the equivalent there (which means essentially implementing it for
drivers/iommu/dma-iommu.cand calling that from 64-bit ARM code).
It sounds like things are getting a bit backwards here: iommu-dma should have nothing to do with this, since if you've explicitly attached the device to your own IOMMU domain then you're already bypassing everything it knows about and has control over. Arch code calling into iommu-dma to do something which makes arch code not use iommu-dma makes very little sense.
AFAICS the only aspect of arm_iommu_detach_device() which actually matters in this case is the set_dma_ops() bit, so what we're really after is a generic way for drivers to say "Hey, I actually have my own MMU (or want to control the one you already know about) so please give me direct DMA ops", which the arch code handles as appropriate (maybe it's also allowed to fail in cases like swiotlb=force or when there is RAM beyond the device's DMA mask).
Robin.
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
A message that is not in the archive (sent off-list or not yet received): e549979d-9f53-a329-da1a-ed5139958762-5wv7dgnIgG8@public.gmane.org
Re: [PATCH v2 2/5] dma-mapping: Introduce dma_iommu_detach_device() API
Quoted 26 lines · Robin Murphy
Quoted 19 lines · Thierry Reding
Quoted 9 lines · Thierry Reding
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Thierry Reding
From: Thierry Reding <[email protected]>
The
dma_iommu_detach_device()API can be used by drivers to forcibly detach a device from an IOMMU that architecture code might have attached to. This is useful for drivers that need explicit control over the IOMMU using the IOMMU API directly.Quoted 8 lines
Quoted 3 lines
Given that no one else implements it making it a generic API seems rather confusing. For now I'd rename it to
arm_dma_iommu_detach_device()and only implement it in arm.That'd be suboptimal because this code is used on both 32-bit and 64-bit ARM. If we make the function 32-bit ARM specific then the driver code would need to use an #ifdef to make sure compilation doesn't break on 64-bit ARM.
Quoted 5 lines
Do you still want me to make this ARM specific? While I haven't encountered this issue on 64-bit ARM yet, I think it would happen there as well, under the right circumstances. I could take a shot at implementing the equivalent there (which means essentially implementing it for
drivers/iommu/dma-iommu.cand calling that from 64-bit ARM code).
Quoted 5 lines
It sounds like things are getting a bit backwards here: iommu-dma should have nothing to do with this, since if you've explicitly attached the device to your own IOMMU domain then you're already bypassing everything it knows about and has control over. Arch code calling into iommu-dma to do something which makes arch code not use iommu-dma makes very little sense.
My understanding is that iommu-dma will set up an IOMMU domain at device probe time anyway. So even if attaching to an own IOMMU domain will end up bypassing iommu-dma, we'd still want to clear up the IOMMU domain and any associated resources, right?
Thierry
Re: [PATCH v2 2/5] dma-mapping: Introduce dma_iommu_detach_device() API
Quoted 33 lines · Thierry Reding
Quoted 26 lines · Robin Murphy
Quoted 19 lines · Thierry Reding
Quoted 9 lines · Thierry Reding
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Thierry Reding
From: Thierry Reding <[email protected]>
The
dma_iommu_detach_device()API can be used by drivers to forcibly detach a device from an IOMMU that architecture code might have attached to. This is useful for drivers that need explicit control over the IOMMU using the IOMMU API directly.Quoted 8 lines
Quoted 3 lines
Given that no one else implements it making it a generic API seems rather confusing. For now I'd rename it to
arm_dma_iommu_detach_device()and only implement it in arm.That'd be suboptimal because this code is used on both 32-bit and 64-bit ARM. If we make the function 32-bit ARM specific then the driver code would need to use an #ifdef to make sure compilation doesn't break on 64-bit ARM.
Quoted 5 lines
Do you still want me to make this ARM specific? While I haven't encountered this issue on 64-bit ARM yet, I think it would happen there as well, under the right circumstances. I could take a shot at implementing the equivalent there (which means essentially implementing it for
drivers/iommu/dma-iommu.cand calling that from 64-bit ARM code).Quoted 5 lines
It sounds like things are getting a bit backwards here: iommu-dma should have nothing to do with this, since if you've explicitly attached the device to your own IOMMU domain then you're already bypassing everything it knows about and has control over. Arch code calling into iommu-dma to do something which makes arch code not use iommu-dma makes very little sense.
Quoted 4 lines
My understanding is that iommu-dma will set up an IOMMU domain at device probe time anyway. So even if attaching to an own IOMMU domain will end up bypassing iommu-dma, we'd still want to clear up the IOMMU domain and any associated resources, right?
The lifetime of a "proper" IOMMU API default domain is that of the iommu_group, so more or less between device_add() and device_del() from the perspective of a device in that group. IOW at least one level below what that device's driver should be messing with. The domain itself is just a little bit of memory and shouldn't have to occupy any hardware resources while it's not active (and yes, I know the ARM SMMU driver is currently a bit crap in that regard).
Robin.
PATCH v2 3/5 ARM: dma-mapping: Implement arch_iommu_detach_device()
In reply to a message not in the archiveFrom: Thierry Reding <[email protected]>
Implement this function to enable drivers from detaching from any IOMMU domains that architecture code might have attached them to so that they can take exclusive control of the IOMMU via the IOMMU API.
---
Changes in v2:
- fix compilation
arch/arm/include/asm/dma-mapping.h | 3 +++ arch/arm/mm/dma-mapping-nommu.c | 4 ++++ arch/arm/mm/dma-mapping.c | 17 +++++++++++++++++ 3 files changed, 24 insertions(+)
arch/arm/include/asm/dma-mapping.h +3 -0
@@ -103,6 +103,9 @@ extern void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,#define arch_teardown_dma_ops arch_teardown_dma_opsextern void arch_teardown_dma_ops (struct device *dev); +#define arch_iommu_detach_device arch_iommu_detach_device +extern void arch_iommu_detach_device (struct device *dev); +/* do not use this function in a driver */ static inline bool is_device_dma_coherent (struct device *dev) {
arch/arm/mm/dma-mapping-nommu.c +4 -0
@@ -242,6 +242,10 @@ void arch_teardown_dma_ops(struct device *dev) { } +void arch_iommu_detach_device (struct device *dev) +{ +} +#define PREALLOC_DMA_DEBUG_ENTRIES 4096static int __init dma_debug_do_init (void )
arch/arm/mm/dma-mapping.c +17 -0
@@ -2423,3 +2423,20 @@ void arch_teardown_dma_ops(struct device *dev)arm_teardown_iommu_dma_ops (dev); } + +void arch_iommu_detach_device (struct device *dev) +{ +#ifdef CONFIG_ARM_DMA_USE_IOMMU +struct dma_iommu_mapping *mapping =to_dma_iommu_mapping (dev); +const struct dma_map_ops *dma_ops; + +if (!mapping) +return ; + +arm_iommu_release_mapping (mapping); +arm_iommu_detach_device (dev); + + dma_ops =arm_get_dma_map_ops (dev->archdata.dma_coherent); +set_dma_ops (dev, dma_ops); +#endif +}
Signature · 1 line
2.17.0
A message that is not in the archive (sent off-list or not yet received): 20180425101051.15349-3-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Re: [PATCH v2 3/5] ARM: dma-mapping: Implement arch_iommu_detach_device()
Quoted 4 lines
arch/arm/mm/dma-mapping.c +4
-0+void arch_iommu_detach_device (struct device *dev) +{ +#ifdef CONFIG_ARM_DMA_USE_IOMMU +struct dma_iommu_mapping *mapping =to_dma_iommu_mapping (dev);
arch/arm/mm/dma-mapping.c void arch_teardown_dma_ops(struct device *dev) · line 2440
Quoted 10 lines
arch/arm/mm/dma-mapping.c +10
-0+const struct dma_map_ops *dma_ops; + +if (!mapping) +return ; + +arm_iommu_release_mapping (mapping); +arm_iommu_detach_device (dev); + + dma_ops =arm_get_dma_map_ops (dev->archdata.dma_coherent); +set_dma_ops (dev, dma_ops);
Why not simply:
set_dma_ops(dev, arm_get_dma_map_ops(dev->archdata.dma_coherent));
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v2 3/5] ARM: dma-mapping: Implement arch_iommu_detach_device()
Quoted 17 lines · Christoph Hellwig
Quoted 4 lines
arch/arm/mm/dma-mapping.c +4
-0+void arch_iommu_detach_device (struct device *dev) +{ +#ifdef CONFIG_ARM_DMA_USE_IOMMU +struct dma_iommu_mapping *mapping =to_dma_iommu_mapping (dev);arch/arm/mm/dma-mapping.c void arch_teardown_dma_ops(struct device *dev) · line 2440
Quoted 10 lines
arch/arm/mm/dma-mapping.c +10
-0+const struct dma_map_ops *dma_ops; + +if (!mapping) +return ; + +arm_iommu_release_mapping (mapping); +arm_iommu_detach_device (dev); + + dma_ops =arm_get_dma_map_ops (dev->archdata.dma_coherent); +set_dma_ops (dev, dma_ops);Why not simply:
Quoted 1 line
set_dma_ops(dev, arm_get_dma_map_ops(dev->archdata.dma_coherent));
I had that initially, but it looked cluttered to me, so I split it up. I don't care much either way, so I can revert to that if you prefer.
Thierry
PATCH v2 4/5 drm/nouveau: tegra: Use dma_iommu_detach_device()
In reply to a message not in the archiveFrom: Thierry Reding <[email protected]>
Use the new dma_iommu_detach_device() function to replace the open-coded equivalent.
--- .../drm/nouveau/nvkm/engine/device/tegra.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-)
drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +2 -17
@@ -20,10 +20,6 @@* DEALINGS IN THE SOFTWARE. */ -#if IS_ENABLED (CONFIG_ARM_DMA_USE_IOMMU ) -#include <asm/dma-iommu.h> -#endif -#include <core/tegra.h> #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER #include "priv.h"
@@ -110,19 +106,8 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)unsigned long pgsize_bitmap;int ret; -#if IS_ENABLED (CONFIG_ARM_DMA_USE_IOMMU ) -if (dev->archdata.mapping) { -struct dma_iommu_mapping *mapping =to_dma_iommu_mapping (dev); - -arm_iommu_release_mapping (mapping); -arm_iommu_detach_device (dev); - -if (dev->archdata.dma_coherent) -set_dma_ops (dev, &arm_coherent_dma_ops); -else -set_dma_ops (dev, &arm_dma_ops); - } -#endif +/* make sure we can use the IOMMU exclusively */ +dma_iommu_detach_device (dev);if (!tdev->func->iommu_bit)return ;
Signature · 1 line
2.17.0
PATCH v2 5/5 ARM: Unconditionally enable ARM_DMA_USE_IOMMU
In reply to a message not in the archiveFrom: Thierry Reding <[email protected]>
The ARM_DMA_USE_IOMMU Kconfig option has side-effects that drivers can not opt into but have to explicitly opt out of. This can lead to subtle bugs that are difficult to track down and not immediately obvious to be related to this Kconfig option.
To avoid this confusion, always enable the option to expose any lurking bugs once and allow any regressions introduced by the DMA/IOMMU code to be caught more quickly in the future.
Note that some drivers still use the Kconfig symbol to provide different code paths depending on what architecture the code runs on (e.g. 32-bit ARM vs. 64-bit ARM which have different and incompatible implementations of the DMA/IOMMU integration code), so leave the symbol in place to keep those drivers working.
For the long term, it is preferable to transition everyone to the generic DMA/IOMMU integration code in drivers/iommu/dma-iommu.c.
---
Changes in v2:
- new patch
arch/arm/Kconfig | 2 +- arch/arm/include/asm/device.h | 6 ------ arch/arm/mm/dma-mapping.c | 18 ------------------ drivers/iommu/Kconfig | 7 ------- drivers/media/platform/Kconfig | 1 - 5 files changed, 1 insertion(+), 33 deletions(-)
arch/arm/Kconfig +1 -1
@@ -124,7 +124,7 @@ config NEED_SG_DMA_LENGTH bool config ARM_DMA_USE_IOMMU - bool + def_bool y select ARM_HAS_SG_CHAIN select NEED_SG_DMA_LENGTH
arch/arm/include/asm/device.h +0 -6
@@ -13,9 +13,7 @@ struct dev_archdata {#ifdef CONFIG_IOMMU_API void *iommu;/* private IOMMU data */ #endif -#ifdef CONFIG_ARM_DMA_USE_IOMMU struct dma_iommu_mapping *mapping; -#endif #ifdef CONFIG_XEN const struct dma_map_ops *dev_dma_ops;#endif
@@ -31,10 +29,6 @@ struct pdev_archdata { #endif }; -#ifdef CONFIG_ARM_DMA_USE_IOMMU #define to_dma_iommu_mapping (dev) ((dev)->archdata.mapping) -#else -#define to_dma_iommu_mapping (dev) NULL -#endif #endif
arch/arm/mm/dma-mapping.c +0 -18
@@ -1174,8 +1174,6 @@ static int __init dma_debug_do_init(void) }core_initcall (dma_debug_do_init); -#ifdef CONFIG_ARM_DMA_USE_IOMMU -static int __dma_info_to_prot (enum dma_data_direction dir,unsigned long attrs) {int prot =0 ;
@@ -2366,20 +2364,6 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)arm_iommu_release_mapping (mapping); } -#else - -static bool arm_setup_iommu_dma_ops (struct device *dev,u64 dma_base,u64 size, -const struct iommu_ops *iommu) -{ -return false; -} - -static void arm_teardown_iommu_dma_ops (struct device *dev) { } - -#define arm_get_iommu_dma_map_ops arm_get_dma_map_ops - -#endif /* CONFIG_ARM_DMA_USE_IOMMU */ -static const struct dma_map_ops *arm_get_dma_map_ops (bool coherent) {return coherent ? &arm_coherent_dma_ops : &arm_dma_ops;
@@ -2426,7 +2410,6 @@ void arch_teardown_dma_ops(struct device *dev)void arch_iommu_detach_device (struct device *dev) { -#ifdef CONFIG_ARM_DMA_USE_IOMMU struct dma_iommu_mapping *mapping =to_dma_iommu_mapping (dev);const struct dma_map_ops *dma_ops;
@@ -2438,5 +2421,4 @@ void arch_iommu_detach_device(struct device *dev) dma_ops =arm_get_dma_map_ops (dev->archdata.dma_coherent);set_dma_ops (dev, dma_ops); -#endif }
drivers/iommu/Kconfig +0 -7
@@ -226,7 +226,6 @@ config ROCKCHIP_IOMMU depends on ARM || ARM64 depends on ARCH_ROCKCHIP || COMPILE_TEST select IOMMU_API - select ARM_DMA_USE_IOMMU help Support for IOMMUs found on Rockchip rk32xx SOCs. These IOMMUs allow virtualization of the address space used by most
@@ -259,7 +258,6 @@ config EXYNOS_IOMMU depends on ARCH_EXYNOS && MMU depends on !CPU_BIG_ENDIAN # revisit driver if we can enable big-endian ptes select IOMMU_API - select ARM_DMA_USE_IOMMU help Support for the IOMMU (System MMU) of Samsung Exynos application processor family. This enables H/W multimedia accelerators to see
@@ -283,7 +281,6 @@ config IPMMU_VMSA depends on ARCH_RENESAS || (COMPILE_TEST && !GENERIC_ATOMIC64) select IOMMU_API select IOMMU_IO_PGTABLE_LPAE - select ARM_DMA_USE_IOMMU help Support for the Renesas VMSA-compatible IPMMU Renesas found in the R-Mobile APE6 and R-Car H2/M2 SoCs.
@@ -304,7 +301,6 @@ config ARM_SMMU depends on (ARM64 || ARM) && MMU select IOMMU_API select IOMMU_IO_PGTABLE_LPAE - select ARM_DMA_USE_IOMMU if ARM help Support for implementations of the ARM System MMU architecture versions 1 and 2.
@@ -344,7 +340,6 @@ config MTK_IOMMU bool "MTK IOMMU Support" depends on ARM || ARM64 depends on ARCH_MEDIATEK || COMPILE_TEST - select ARM_DMA_USE_IOMMU select IOMMU_API select IOMMU_DMA select IOMMU_IO_PGTABLE_ARMV7S
@@ -361,7 +356,6 @@ config MTK_IOMMU_V1 bool "MTK IOMMU Version 1 (M4U gen1) Support" depends on ARM depends on ARCH_MEDIATEK || COMPILE_TEST - select ARM_DMA_USE_IOMMU select IOMMU_API select MEMORY select MTK_SMI
@@ -379,7 +373,6 @@ config QCOM_IOMMU depends on HAS_DMA select IOMMU_API select IOMMU_IO_PGTABLE_LPAE - select ARM_DMA_USE_IOMMU help Support for IOMMU on certain Qualcomm SoCs.
drivers/media/platform/Kconfig +0 -1
@@ -66,7 +66,6 @@ config VIDEO_OMAP3 depends on (ARCH_OMAP3 && OMAP_IOMMU) || COMPILE_TEST depends on COMMON_CLK depends on HAS_DMA && OF - select ARM_DMA_USE_IOMMU if OMAP_IOMMU select VIDEOBUF2_DMA_CONTIG select MFD_SYSCON select V4L2_FWNODE
Signature · 6 lines
2.17.0 _______________________________________________ Nouveau mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): 20180425101051.15349-5-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Re: [PATCH v2 5/5] ARM: Unconditionally enable ARM_DMA_USE_IOMMU
Quoted 37 lines · Thierry Reding
From: Thierry Reding <[email protected]>
The
ARM_DMA_USE_IOMMUKconfigoption has side-effects that drivers can not opt into but have to explicitly opt out of. This can lead to subtle bugs that are difficult to track down and not immediately obvious to be related to thisKconfigoption.To avoid this confusion, always enable the option to expose any lurking bugs once and allow any regressions introduced by the DMA/IOMMU code to be caught more quickly in the future.
Note that some drivers still use the
Kconfigsymbol to provide different code paths depending on what architecture the code runs on (e.g. 32-bit ARM vs. 64-bit ARM which have different and incompatible implementations of the DMA/IOMMU integration code), so leave the symbol in place to keep those drivers working.For the long term, it is preferable to transition everyone to the generic DMA/IOMMU integration code in
drivers/iommu/dma-iommu.c.Signed-off-by Thierry Reding <[email protected]>---
Changes in v2:
- new patcharch/arm/Kconfig | 2 +- arch/arm/include/asm/device.h | 6 ------ arch/arm/mm/dma-mapping.c | 18 ------------------ drivers/iommu/Kconfig | 7 ------- drivers/media/platform/Kconfig | 1 - 5 files changed, 1 insertion(+), 33 deletions(-)arch/arm/Kconfig +0
-0
arch/arm/Kconfig config NEED_SG_DMA_LENGTH · line 129
Quoted 7 lines
arch/arm/Kconfig +1
-1@@ -124,7 +124,7 @@ config NEED_SG_DMA_LENGTH bool config ARM_DMA_USE_IOMMU - bool + def_bool y select ARM_HAS_SG_CHAIN select NEED_SG_DMA_LENGTH
This doesn't work - as has recently been discussed with hch, we can't globally enable NEED_SG_DMA_LENGTH on ARM - the ARM architecture pre-dates the addition of the DMA length member in the scatterlist, and not every machine supports the splitting of the DMA length from the non-DMA length member. Hence, this will cause a regression, sorry.
Signature · 3 lines
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up According to speedtest.net: 8.21Mbps down 510kbps up
Re: [PATCH v2 5/5] ARM: Unconditionally enable ARM_DMA_USE_IOMMU
Quoted 4 lines · Russell King - ARM Linux
Quoted 4 lines
config
ARM_DMA_USE_IOMMUarch/arm/Kconfig +1
-1- bool + def_bool y select ARM_HAS_SG_CHAIN
Quoted 8 lines
Quoted 1 line
select
NEED_SG_DMA_LENGTHThis doesn't work - as has recently been discussed with hch, we can't globally enable
NEED_SG_DMA_LENGTHon ARM - the ARM architecture pre-dates the addition of the DMA length member in the scatterlist, and not every machine supports the splitting of the DMA length from the non-DMA length member. Hence, this will cause a regression, sorry.
Agreed as-is. However supporting it everywhere should not be much work, I'll take a look at it.
The series seems to miss a cover letter.
Also I really think this patch original patch shouldn't be in the proper series.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 4 lines · Christoph Hellwig
The series seems to miss a cover letter.
Also I really think this patch original patch shouldn't be in the proper series.
I added a note explaining why I included this. Not everyone in this discussion had seen the patch and therefore may not be aware of the problem that the series attempts to fix. I agree that it shouldn't be merged as part of the series, though.
Thierry
Quoted 17 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Depending on the kernel configuration, early ARM architecture setup code may have attached the GPU to a DMA/IOMMU mapping that transparently uses the IOMMU to back the DMA API. Tegra requires special handling for IOMMU backed buffers (a special bit in the GPU's MMU page tables indicates the memory path to take: via the SMMU or directly to the memory controller). Transparently backing DMA memory with an IOMMU prevents Nouveau from properly handling such memory accesses and causes memory access faults.
As a side-note: buffers other than those allocated in instance memory don't need to be physically contiguous from the GPU's perspective since the GPU can map them into contiguous buffers using its own MMU. Mapping these buffers through the IOMMU is unnecessary and will even lead to performance degradation because of the additional translation.
Signed-off-by Thierry Reding <[email protected]>
Quoted 8 lines
---
I had already sent this out independently to fix a regression that was introduced in v4.16, but then Christoph pointed out that it should've been sent to a wider audience and should use a core API rather than calling into architecture code directly.I've added it to this series for easier reference and to show the need for the new API.
This is good stuff, I am struggling with something similar on ARM64. One problem that I wasn't able to fully solve cleanly was that for arm-smmu the SMMU HW resources are not released until the domain itself is destroyed and I never quite figured out a way to swap the default domain cleanly.
This is a problem for the MSM GPU because not only do we run our own IOMMU as you do we also have a hardware dependency to use context bank 0 to asynchronously switch the pagetable during rendering.
I'm not sure if this is a problem you have encountered. In any event, this code gets us a little bit further down the path and at least there is somebody else out there in the cold dark world that understands my pain. :)
For your interest, here was my half-hearted attempt to avoid creating DMA domains in the first place based on a blacklist to try to spur a bit of
discussion: https://patchwork.freedesktop.org/series/41573/
Jordan
Signature · 6 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
A message that is not in the archive (sent off-list or not yet received): 20180425152849.GA2447-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org
Quoted 32 lines · Jordan Crouse
Quoted 17 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Depending on the kernel configuration, early ARM architecture setup code may have attached the GPU to a DMA/IOMMU mapping that transparently uses the IOMMU to back the DMA API. Tegra requires special handling for IOMMU backed buffers (a special bit in the GPU's MMU page tables indicates the memory path to take: via the SMMU or directly to the memory controller). Transparently backing DMA memory with an IOMMU prevents Nouveau from properly handling such memory accesses and causes memory access faults.
As a side-note: buffers other than those allocated in instance memory don't need to be physically contiguous from the GPU's perspective since the GPU can map them into contiguous buffers using its own MMU. Mapping these buffers through the IOMMU is unnecessary and will even lead to performance degradation because of the additional translation.
Signed-off-by Thierry Reding <[email protected]>Quoted 8 lines
---
I had already sent this out independently to fix a regression that was introduced in v4.16, but then Christoph pointed out that it should've been sent to a wider audience and should use a core API rather than calling into architecture code directly.I've added it to this series for easier reference and to show the need for the new API.
This is good stuff, I am struggling with something similar on ARM64. One problem that I wasn't able to fully solve cleanly was that for arm-smmu the SMMU HW resources are not released until the domain itself is destroyed and I never quite figured out a way to swap the default domain cleanly.
Quoted 5 lines
This is a problem for the MSM GPU because not only do we run our own IOMMU as you do we also have a hardware dependency to use context bank 0 to asynchronously switch the pagetable during rendering.
I'm not sure if this is a problem you have encountered.
I don't think I have. Recent chips have similar capabilities, but they don't have the restriction to a context bank, as far as I understand. Adding Mikko who's had more exposure to this.
Quoted 3 lines
In any event, this code
gets us a little bit further down the path and at least there is somebody else out there in the cold dark world that understands my pain. :)
This doesn't actually fix anything on 64-bit ARM, and oddly enough I haven't run into this issue myself on 64-bit ARM either. I think the reason is that I haven't tested Nouveau on Tegra186 yet, which is the first SoC which has an ARM SMMU. On prior 64-bit ARM chips we've used the custom Tegra SMMU and that driver simply forbids creating any DMA domains, so it will allow only explicit usage of the IOMMU API. There is code in the generic DMA/IOMMU integration layer to not use the DMA API with non-DMA IOMMU domains, but that's not true on 32-bit ARM, unfortunately. It's entirely possible that Tegra186 will show exactly the same problem that you are describing.
We do use the IOMMU API explicitly in the Tegra DRM driver as well, and that is something that I've tested on Tegra186 and that I know to be working. However, the reason why it works there is that the IOMMU group will contain multiple display controllers, which will again trigger a special case that will prevent the DMA/IOMMU integration from setting up a DMA domain for use with those devices.
Quoted 3 lines
For your interest, here was my half-hearted attempt to avoid creating DMA domains in the first place based on a blacklist to try to spur a bit of
discussion: https://patchwork.freedesktop.org/series/41573/
This looks very interesting and simple, but I can imagine that it will see significant pushback from the ARM SMMU maintainers (if not complete silence), because it adds SoC-specific knowledge to an otherwise fully generic driver. Having the GPU driver explicitly detach from the IOMMU domain sounds like a better option, but I don't see how that would help with the context bank issue that you're seeing.
One other possibility that I can imagine is to add something to struct device that could be used by arch_setup_dma_ops() to not attach any of the IOMMU-backed DMA operations to the device. Unfortunately that code is called before the driver's ->probe() implementation is called, so a driver doesn't have an opportunity to set it. Something like of_dma_configure() could still set that up, perhaps based on some DT property, though I can already hear the NAK from DT maintainers because this is, after all, policy, not hardware description.
The last solution that I can think of that might allow us to do this is to add a flag to struct device_driver (bool explicit_iommu?) that will be used by the DMA/IOMMU setup code to decide whether or not to attach to the IOMMU automatically.
Though, again, I'm not sure that would actually solve your bank problem. That's really something I don't see any other solution than to fix it in the ARM SMMU driver. Perhaps context bank 0 can always be reserved for non-DMA domains?
Thierry
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau
Quoted 37 lines · Thierry Reding
Quoted 36 lines · Jordan Crouse
Quoted 17 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Depending on the kernel configuration, early ARM architecture setup code may have attached the GPU to a DMA/IOMMU mapping that transparently uses the IOMMU to back the DMA API. Tegra requires special handling for IOMMU backed buffers (a special bit in the GPU's MMU page tables indicates the memory path to take: via the SMMU or directly to the memory controller). Transparently backing DMA memory with an IOMMU prevents Nouveau from properly handling such memory accesses and causes memory access faults.
As a side-note: buffers other than those allocated in instance memory don't need to be physically contiguous from the GPU's perspective since the GPU can map them into contiguous buffers using its own MMU. Mapping these buffers through the IOMMU is unnecessary and will even lead to performance degradation because of the additional translation.
Signed-off-by Thierry Reding <[email protected]>Quoted 8 lines
---
I had already sent this out independently to fix a regression that was introduced in v4.16, but then Christoph pointed out that it should've been sent to a wider audience and should use a core API rather than calling into architecture code directly.I've added it to this series for easier reference and to show the need for the new API.
This is good stuff, I am struggling with something similar on ARM64. One problem that I wasn't able to fully solve cleanly was that for arm-smmu the SMMU HW resources are not released until the domain itself is destroyed and I never quite figured out a way to swap the default domain cleanly.
This is a problem for the MSM GPU because not only do we run our own IOMMU as you do we also have a hardware dependency to use context bank 0 to asynchronously switch the pagetable during rendering.
Quoted 5 lines
Quoted 1 line
I'm not sure if this is a problem you have encountered.
I don't think I have. Recent chips have similar capabilities, but they don't have the restriction to a context bank, as far as I understand. Adding Mikko who's had more exposure to this.
IIRC the only way I've gotten Host1x to work on Tegra186 with IOMMU enabled is doing the equivalent of this patch (or actually using the DMA API, which may be possible but has some potential issues).
As you said, we don't have a limitation regarding the context bank or similar - Host1x handles context switching by changing the sent stream ID on the fly (which is quite difficult to deal with from kernel point of view as well), and the actual GPU has its own MMU.
Thanks,
Mikko
Quoted 48 lines
Quoted 4 lines
In any event, this code
gets us a little bit further down the path and at least there is somebody else out there in the cold dark world that understands my pain. :)This doesn't actually fix anything on 64-bit ARM, and oddly enough I haven't run into this issue myself on 64-bit ARM either. I think the reason is that I haven't tested Nouveau on Tegra186 yet, which is the first SoC which has an ARM SMMU. On prior 64-bit ARM chips we've used the custom Tegra SMMU and that driver simply forbids creating any DMA domains, so it will allow only explicit usage of the IOMMU API. There is code in the generic DMA/IOMMU integration layer to not use the DMA API with non-DMA IOMMU domains, but that's not true on 32-bit ARM, unfortunately. It's entirely possible that Tegra186 will show exactly the same problem that you are describing.
We do use the IOMMU API explicitly in the Tegra DRM driver as well, and that is something that I've tested on Tegra186 and that I know to be working. However, the reason why it works there is that the IOMMU group will contain multiple display controllers, which will again trigger a special case that will prevent the DMA/IOMMU integration from setting up a DMA domain for use with those devices.
Quoted 3 lines
For your interest, here was my half-hearted attempt to avoid creating DMA domains in the first place based on a blacklist to try to spur a bit of
discussion: https://patchwork.freedesktop.org/series/41573/This looks very interesting and simple, but I can imagine that it will see significant pushback from the ARM SMMU maintainers (if not complete silence), because it adds SoC-specific knowledge to an otherwise fully generic driver. Having the GPU driver explicitly detach from the IOMMU domain sounds like a better option, but I don't see how that would help with the context bank issue that you're seeing.
One other possibility that I can imagine is to add something to struct device that could be used by
arch_setup_dma_ops()to not attach any of the IOMMU-backed DMA operations to the device. Unfortunately that code is called before the driver's ->probe() implementation is called, so a driver doesn't have an opportunity to set it. Something likeof_dma_configure()could still set that up, perhaps based on some DT property, though I can already hear the NAK from DT maintainers because this is, after all, policy, not hardware description.The last solution that I can think of that might allow us to do this is to add a flag to struct
device_driver(boolexplicit_iommu?) that will be used by the DMA/IOMMU setup code to decide whether or not to attach to the IOMMU automatically.
Quoted 7 lines
Though, again, I'm not sure that would actually solve your bank problem. That's really something I don't see any other solution than to fix it in the ARM SMMU driver. Perhaps context bank 0 can always be reserved for non-DMA domains?
Thierry
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
A message that is not in the archive (sent off-list or not yet received): fd6e0d90-7614-296b-2927-7b2745e8fbde-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org
Quoted 44 lines · Mikko Perttunen
Quoted 37 lines · Thierry Reding
Quoted 36 lines · Jordan Crouse
Quoted 17 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Depending on the kernel configuration, early ARM architecture setup code may have attached the GPU to a DMA/IOMMU mapping that transparently uses the IOMMU to back the DMA API. Tegra requires special handling for IOMMU backed buffers (a special bit in the GPU's MMU page tables indicates the memory path to take: via the SMMU or directly to the memory controller). Transparently backing DMA memory with an IOMMU prevents Nouveau from properly handling such memory accesses and causes memory access faults.
As a side-note: buffers other than those allocated in instance memory don't need to be physically contiguous from the GPU's perspective since the GPU can map them into contiguous buffers using its own MMU. Mapping these buffers through the IOMMU is unnecessary and will even lead to performance degradation because of the additional translation.
Signed-off-by Thierry Reding <[email protected]>Quoted 8 lines
---
I had already sent this out independently to fix a regression that was introduced in v4.16, but then Christoph pointed out that it should've been sent to a wider audience and should use a core API rather than calling into architecture code directly.I've added it to this series for easier reference and to show the need for the new API.
This is good stuff, I am struggling with something similar on ARM64. One problem that I wasn't able to fully solve cleanly was that for arm-smmu the SMMU HW resources are not released until the domain itself is destroyed and I never quite figured out a way to swap the default domain cleanly.
This is a problem for the MSM GPU because not only do we run our own IOMMU as you do we also have a hardware dependency to use context bank 0 to asynchronously switch the pagetable during rendering.
Quoted 5 lines
Quoted 1 line
I'm not sure if this is a problem you have encountered.
I don't think I have. Recent chips have similar capabilities, but they don't have the restriction to a context bank, as far as I understand. Adding Mikko who's had more exposure to this.
Quoted 8 lines
IIRC the only way I've gotten Host1x to work on Tegra186 with IOMMU enabled is doing the equivalent of this patch (or actually using the DMA API, which may be possible but has some potential issues).
As you said, we don't have a limitation regarding the context bank or similar - Host1x handles context switching by changing the sent stream ID on the fly (which is quite difficult to deal with from kernel point of view as well), and the actual GPU has its own MMU.
One instance where we still need the system MMU for GPU is to implement support for big pages, which is required in order to do compression and better performance in some other use-cases. I don't think we'll need anything fancy like context switching in that case, though, because we would use the SMMU exclusively to make sparse allocations look contiguous to the GPU, so all of the per-process protection would still be achieved via the GPU MMU.
Thierry
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau