[3/4] ARM: dma-mapping: Implement arch_iommu_detach_device()

Submitted by Thierry Reding on April 25, 2018, 9:18 a.m.

Details

Message ID 20180425091815.16264-3-thierry.reding@gmail.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Nouveau

Not browsing as part of any series.

Commit Message

Thierry Reding April 25, 2018, 9:18 a.m.
From: Thierry Reding <treding@nvidia.com>

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.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 arch/arm/include/asm/dma-mapping.h |  3 +++
 arch/arm/mm/dma-mapping-nommu.c    |  4 ++++
 arch/arm/mm/dma-mapping.c          | 19 +++++++++++++++++++
 3 files changed, 26 insertions(+)

Patch hide | download patch | download mbox

diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 8436f6ade57d..d6d5bd44f962 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -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_ops
 extern 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)
 {
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index 619f24a42d09..60fef97d8452 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -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	4096
 
 static int __init dma_debug_do_init(void)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 8c398fedbbb6..1957938d8c9c 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2366,6 +2366,21 @@  static void arm_teardown_iommu_dma_ops(struct device *dev)
 	arm_iommu_release_mapping(mapping);
 }
 
+void arch_iommu_detach_device(struct device *dev)
+{
+	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);
+}
+
 #else
 
 static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
@@ -2378,6 +2393,10 @@  static void arm_teardown_iommu_dma_ops(struct device *dev) { }
 
 #define arm_get_iommu_dma_map_ops arm_get_dma_map_ops
 
+void arch_iommu_detach_device(struct device *dev)
+{
+}
+
 #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
 
 static const struct dma_map_ops *arm_get_dma_map_ops(bool coherent)

Comments

On Wed, Apr 25, 2018 at 11:18:14AM +0200, Thierry Reding wrote:
[...]
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 8c398fedbbb6..1957938d8c9c 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -2366,6 +2366,21 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
>  	arm_iommu_release_mapping(mapping);
>  }
>  
> +void arch_iommu_detach_device(struct device *dev)
> +{
> +	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);
> +}

Oh, the irony! This doesn't actually build and I failed to notice
because I forgot to enable ARM_DMA_USE_IOMMU...

Sorry about that, but I think we can use this as basis to discuss
whether the API is good and I'll make sure to properly test the next
revision before sending it out.

Thierry
Hi Thierry,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.17-rc2 next-20180424]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Thierry-Reding/drm-nouveau-tegra-Detach-from-ARM-DMA-IOMMU-mapping/20180426-140854
config: arm-omap2plus_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All error/warnings (new ones prefixed by >>):

   arch/arm/mm/dma-mapping.c: In function 'arch_iommu_detach_device':
>> arch/arm/mm/dma-mapping.c:2380:12: error: implicit declaration of function 'arm_get_dma_map_ops'; did you mean 'arm_get_iommu_dma_map_ops'? [-Werror=implicit-function-declaration]
     dma_ops = arm_get_dma_map_ops(dev->archdata.dma_coherent);
               ^~~~~~~~~~~~~~~~~~~
               arm_get_iommu_dma_map_ops
>> arch/arm/mm/dma-mapping.c:2380:10: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     dma_ops = arm_get_dma_map_ops(dev->archdata.dma_coherent);
             ^
   arch/arm/mm/dma-mapping.c: At top level:
>> arch/arm/mm/dma-mapping.c:2402:34: error: conflicting types for 'arm_get_dma_map_ops'
    static const struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
                                     ^~~~~~~~~~~~~~~~~~~
   arch/arm/mm/dma-mapping.c:2380:12: note: previous implicit declaration of 'arm_get_dma_map_ops' was here
     dma_ops = arm_get_dma_map_ops(dev->archdata.dma_coherent);
               ^~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +2380 arch/arm/mm/dma-mapping.c

  2368	
  2369	void arch_iommu_detach_device(struct device *dev)
  2370	{
  2371		struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
  2372		const struct dma_map_ops *dma_ops;
  2373	
  2374		if (!mapping)
  2375			return;
  2376	
  2377		arm_iommu_release_mapping(mapping);
  2378		arm_iommu_detach_device(dev);
  2379	
> 2380		dma_ops = arm_get_dma_map_ops(dev->archdata.dma_coherent);
  2381		set_dma_ops(dev, dma_ops);
  2382	}
  2383	
  2384	#else
  2385	
  2386	static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
  2387					    const struct iommu_ops *iommu)
  2388	{
  2389		return false;
  2390	}
  2391	
  2392	static void arm_teardown_iommu_dma_ops(struct device *dev) { }
  2393	
  2394	#define arm_get_iommu_dma_map_ops arm_get_dma_map_ops
  2395	
  2396	void arch_iommu_detach_device(struct device *dev)
  2397	{
  2398	}
  2399	
  2400	#endif	/* CONFIG_ARM_DMA_USE_IOMMU */
  2401	
> 2402	static const struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
  2403	{
  2404		return coherent ? &arm_coherent_dma_ops : &arm_dma_ops;
  2405	}
  2406	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation