All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1] drm/tegra: Detach devices from IOMMU DMA domain on arm32
@ 2018-08-19 14:24 Dmitry Osipenko
  2018-08-19 14:24 ` [PATCH v1] gpu: host1x: Detach Host1x " Dmitry Osipenko
  2018-09-26 15:24 ` [PATCH v1] drm/tegra: Detach devices " Thierry Reding
  0 siblings, 2 replies; 4+ messages in thread
From: Dmitry Osipenko @ 2018-08-19 14:24 UTC (permalink / raw)
  To: Thierry Reding, Mikko Perttunen; +Cc: linux-tegra, dri-devel

All Tegra DRM devices are getting attached to an implicit IOMMU DMA
domain if CONFIG_ARM_DMA_USE_IOMMU=y. Since Tegra DRM driver manages IOMMU
by itself, the devices must be detached from the implicit domain using
arch-specific IOMMU-API. Note that this works only for arm32 and not for
arm64, which will remain broken if CONFIG_IOMMU_DMA is enabled.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/drm.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index a2bd5876c633..b2ac2411e0ff 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -15,6 +15,10 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
+#include <asm/dma-iommu.h>
+#endif
+
 #include "drm.h"
 #include "gem.h"
 
@@ -1068,6 +1072,14 @@ struct iommu_group *host1x_client_iommu_attach(struct host1x_client *client,
 		}
 
 		if (!shared || (shared && (group != tegra->group))) {
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
+			if (client->dev->archdata.mapping) {
+				struct dma_iommu_mapping *mapping =
+					to_dma_iommu_mapping(client->dev);
+				arm_iommu_detach_device(client->dev);
+				arm_iommu_release_mapping(mapping);
+			}
+#endif
 			err = iommu_attach_group(tegra->domain, group);
 			if (err < 0) {
 				iommu_group_put(group);
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v1] gpu: host1x: Detach Host1x from IOMMU DMA domain on arm32
  2018-08-19 14:24 [PATCH v1] drm/tegra: Detach devices from IOMMU DMA domain on arm32 Dmitry Osipenko
@ 2018-08-19 14:24 ` Dmitry Osipenko
  2018-08-20 17:35   ` kbuild test robot
  2018-09-26 15:24 ` [PATCH v1] drm/tegra: Detach devices " Thierry Reding
  1 sibling, 1 reply; 4+ messages in thread
From: Dmitry Osipenko @ 2018-08-19 14:24 UTC (permalink / raw)
  To: Thierry Reding, Mikko Perttunen; +Cc: linux-tegra, dri-devel

Host1x is getting attached to an implicit IOMMU DMA domain if
CONFIG_ARM_DMA_USE_IOMMU=y. Since Host1x driver manages IOMMU by
itself, Host1x device must be detached from the implicit domain using
arch-specific IOMMU-API. Note that this works only for arm32 and not
for arm64, which will remain broken if CONFIG_IOMMU_DMA is enabled.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/host1x/dev.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index d88073e7d22d..47624f20718d 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -29,6 +29,10 @@
 #include <trace/events/host1x.h>
 #undef CREATE_TRACE_POINTS
 
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
+#include <asm/dma-iommu.h>
+#endif
+
 #include "bus.h"
 #include "channel.h"
 #include "debug.h"
@@ -236,6 +240,14 @@ static int host1x_probe(struct platform_device *pdev)
 			goto put_cache;
 		}
 
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
+		if (pdev->dev->archdata.mapping) {
+			struct dma_iommu_mapping *mapping =
+					to_dma_iommu_mapping(pdev->dev);
+			arm_iommu_detach_device(pdev->dev);
+			arm_iommu_release_mapping(mapping);
+		}
+#endif
 		err = iommu_attach_group(host->domain, host->group);
 		if (err) {
 			if (err == -ENODEV) {
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v1] gpu: host1x: Detach Host1x from IOMMU DMA domain on arm32
  2018-08-19 14:24 ` [PATCH v1] gpu: host1x: Detach Host1x " Dmitry Osipenko
@ 2018-08-20 17:35   ` kbuild test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2018-08-20 17:35 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: linux-tegra, Thierry Reding, Mikko Perttunen, kbuild-all, dri-devel

[-- Attachment #1: Type: text/plain, Size: 9341 bytes --]

Hi Dmitry,

I love your patch! Yet something to improve:

[auto build test ERROR on tegra-drm/drm/tegra/for-next]
[also build test ERROR on v4.18 next-20180820]
[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/Dmitry-Osipenko/gpu-host1x-Detach-Host1x-from-IOMMU-DMA-domain-on-arm32/20180820-225630
base:   git://anongit.freedesktop.org/tegra/linux.git drm/tegra/for-next
config: arm-allmodconfig (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
        GCC_VERSION=7.2.0 make.cross ARCH=arm 

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

   drivers/gpu/host1x/dev.c: In function 'host1x_probe':
>> drivers/gpu/host1x/dev.c:241:16: error: invalid type argument of '->' (have 'struct device')
      if (pdev->dev->archdata.mapping) {
                   ^~
   In file included from include/linux/device.h:28:0,
                    from include/linux/dma-mapping.h:7,
                    from drivers/gpu/host1x/dev.c:20:
>> arch/arm/include/asm/device.h:35:41: error: invalid type argument of '->' (have 'struct device')
    #define to_dma_iommu_mapping(dev) ((dev)->archdata.mapping)
                                            ^
>> drivers/gpu/host1x/dev.c:243:6: note: in expansion of macro 'to_dma_iommu_mapping'
         to_dma_iommu_mapping(pdev->dev);
         ^~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/host1x/dev.c:244:28: error: incompatible type for argument 1 of 'arm_iommu_detach_device'
       arm_iommu_detach_device(pdev->dev);
                               ^~~~
   In file included from drivers/gpu/host1x/dev.c:33:0:
   arch/arm/include/asm/dma-iommu.h:36:6: note: expected 'struct device *' but argument is of type 'struct device'
    void arm_iommu_detach_device(struct device *dev);
         ^~~~~~~~~~~~~~~~~~~~~~~
--
   drivers/gpu//host1x/dev.c: In function 'host1x_probe':
   drivers/gpu//host1x/dev.c:241:16: error: invalid type argument of '->' (have 'struct device')
      if (pdev->dev->archdata.mapping) {
                   ^~
   In file included from include/linux/device.h:28:0,
                    from include/linux/dma-mapping.h:7,
                    from drivers/gpu//host1x/dev.c:20:
>> arch/arm/include/asm/device.h:35:41: error: invalid type argument of '->' (have 'struct device')
    #define to_dma_iommu_mapping(dev) ((dev)->archdata.mapping)
                                            ^
   drivers/gpu//host1x/dev.c:243:6: note: in expansion of macro 'to_dma_iommu_mapping'
         to_dma_iommu_mapping(pdev->dev);
         ^~~~~~~~~~~~~~~~~~~~
   drivers/gpu//host1x/dev.c:244:28: error: incompatible type for argument 1 of 'arm_iommu_detach_device'
       arm_iommu_detach_device(pdev->dev);
                               ^~~~
   In file included from drivers/gpu//host1x/dev.c:33:0:
   arch/arm/include/asm/dma-iommu.h:36:6: note: expected 'struct device *' but argument is of type 'struct device'
    void arm_iommu_detach_device(struct device *dev);
         ^~~~~~~~~~~~~~~~~~~~~~~

vim +241 drivers/gpu/host1x/dev.c

   143	
   144	static int host1x_probe(struct platform_device *pdev)
   145	{
   146		struct host1x *host;
   147		struct resource *regs, *hv_regs = NULL;
   148		int syncpt_irq;
   149		int err;
   150	
   151		host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
   152		if (!host)
   153			return -ENOMEM;
   154	
   155		host->info = of_device_get_match_data(&pdev->dev);
   156	
   157		if (host->info->has_hypervisor) {
   158			regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vm");
   159			if (!regs) {
   160				dev_err(&pdev->dev, "failed to get vm registers\n");
   161				return -ENXIO;
   162			}
   163	
   164			hv_regs = platform_get_resource_byname(pdev, IORESOURCE_MEM,
   165							       "hypervisor");
   166			if (!hv_regs) {
   167				dev_err(&pdev->dev,
   168					"failed to get hypervisor registers\n");
   169				return -ENXIO;
   170			}
   171		} else {
   172			regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   173			if (!regs) {
   174				dev_err(&pdev->dev, "failed to get registers\n");
   175				return -ENXIO;
   176			}
   177		}
   178	
   179		syncpt_irq = platform_get_irq(pdev, 0);
   180		if (syncpt_irq < 0) {
   181			dev_err(&pdev->dev, "failed to get IRQ: %d\n", syncpt_irq);
   182			return syncpt_irq;
   183		}
   184	
   185		mutex_init(&host->devices_lock);
   186		INIT_LIST_HEAD(&host->devices);
   187		INIT_LIST_HEAD(&host->list);
   188		host->dev = &pdev->dev;
   189	
   190		/* set common host1x device data */
   191		platform_set_drvdata(pdev, host);
   192	
   193		host->regs = devm_ioremap_resource(&pdev->dev, regs);
   194		if (IS_ERR(host->regs))
   195			return PTR_ERR(host->regs);
   196	
   197		if (host->info->has_hypervisor) {
   198			host->hv_regs = devm_ioremap_resource(&pdev->dev, hv_regs);
   199			if (IS_ERR(host->hv_regs))
   200				return PTR_ERR(host->hv_regs);
   201		}
   202	
   203		dma_set_mask_and_coherent(host->dev, host->info->dma_mask);
   204	
   205		if (host->info->init) {
   206			err = host->info->init(host);
   207			if (err)
   208				return err;
   209		}
   210	
   211		host->clk = devm_clk_get(&pdev->dev, NULL);
   212		if (IS_ERR(host->clk)) {
   213			dev_err(&pdev->dev, "failed to get clock\n");
   214			err = PTR_ERR(host->clk);
   215			return err;
   216		}
   217	
   218		host->rst = devm_reset_control_get(&pdev->dev, "host1x");
   219		if (IS_ERR(host->rst)) {
   220			err = PTR_ERR(host->rst);
   221			dev_err(&pdev->dev, "failed to get reset: %d\n", err);
   222			return err;
   223		}
   224	
   225		host->group = iommu_group_get(&pdev->dev);
   226		if (host->group) {
   227			struct iommu_domain_geometry *geometry;
   228			unsigned long order;
   229	
   230			err = iova_cache_get();
   231			if (err < 0)
   232				goto put_group;
   233	
   234			host->domain = iommu_domain_alloc(&platform_bus_type);
   235			if (!host->domain) {
   236				err = -ENOMEM;
   237				goto put_cache;
   238			}
   239	
   240	#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
 > 241			if (pdev->dev->archdata.mapping) {
   242				struct dma_iommu_mapping *mapping =
 > 243						to_dma_iommu_mapping(pdev->dev);
 > 244				arm_iommu_detach_device(pdev->dev);
   245				arm_iommu_release_mapping(mapping);
   246			}
   247	#endif
   248			err = iommu_attach_group(host->domain, host->group);
   249			if (err) {
   250				if (err == -ENODEV) {
   251					iommu_domain_free(host->domain);
   252					host->domain = NULL;
   253					iova_cache_put();
   254					iommu_group_put(host->group);
   255					host->group = NULL;
   256					goto skip_iommu;
   257				}
   258	
   259				goto fail_free_domain;
   260			}
   261	
   262			geometry = &host->domain->geometry;
   263	
   264			order = __ffs(host->domain->pgsize_bitmap);
   265			init_iova_domain(&host->iova, 1UL << order,
   266					 geometry->aperture_start >> order);
   267			host->iova_end = geometry->aperture_end;
   268		}
   269	
   270	skip_iommu:
   271		err = host1x_channel_list_init(&host->channel_list,
   272					       host->info->nb_channels);
   273		if (err) {
   274			dev_err(&pdev->dev, "failed to initialize channel list\n");
   275			goto fail_detach_device;
   276		}
   277	
   278		err = clk_prepare_enable(host->clk);
   279		if (err < 0) {
   280			dev_err(&pdev->dev, "failed to enable clock\n");
   281			goto fail_free_channels;
   282		}
   283	
   284		err = reset_control_deassert(host->rst);
   285		if (err < 0) {
   286			dev_err(&pdev->dev, "failed to deassert reset: %d\n", err);
   287			goto fail_unprepare_disable;
   288		}
   289	
   290		err = host1x_syncpt_init(host);
   291		if (err) {
   292			dev_err(&pdev->dev, "failed to initialize syncpts\n");
   293			goto fail_reset_assert;
   294		}
   295	
   296		err = host1x_intr_init(host, syncpt_irq);
   297		if (err) {
   298			dev_err(&pdev->dev, "failed to initialize interrupts\n");
   299			goto fail_deinit_syncpt;
   300		}
   301	
   302		host1x_debug_init(host);
   303	
   304		err = host1x_register(host);
   305		if (err < 0)
   306			goto fail_deinit_intr;
   307	
   308		return 0;
   309	
   310	fail_deinit_intr:
   311		host1x_intr_deinit(host);
   312	fail_deinit_syncpt:
   313		host1x_syncpt_deinit(host);
   314	fail_reset_assert:
   315		reset_control_assert(host->rst);
   316	fail_unprepare_disable:
   317		clk_disable_unprepare(host->clk);
   318	fail_free_channels:
   319		host1x_channel_list_free(&host->channel_list);
   320	fail_detach_device:
   321		if (host->group && host->domain) {
   322			put_iova_domain(&host->iova);
   323			iommu_detach_group(host->domain, host->group);
   324		}
   325	fail_free_domain:
   326		if (host->domain)
   327			iommu_domain_free(host->domain);
   328	put_cache:
   329		if (host->group)
   330			iova_cache_put();
   331	put_group:
   332		iommu_group_put(host->group);
   333	
   334		return err;
   335	}
   336	

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 65073 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v1] drm/tegra: Detach devices from IOMMU DMA domain on arm32
  2018-08-19 14:24 [PATCH v1] drm/tegra: Detach devices from IOMMU DMA domain on arm32 Dmitry Osipenko
  2018-08-19 14:24 ` [PATCH v1] gpu: host1x: Detach Host1x " Dmitry Osipenko
@ 2018-09-26 15:24 ` Thierry Reding
  1 sibling, 0 replies; 4+ messages in thread
From: Thierry Reding @ 2018-09-26 15:24 UTC (permalink / raw)
  To: Dmitry Osipenko; +Cc: linux-tegra, Mikko Perttunen, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 614 bytes --]

On Sun, Aug 19, 2018 at 05:24:20PM +0300, Dmitry Osipenko wrote:
> All Tegra DRM devices are getting attached to an implicit IOMMU DMA
> domain if CONFIG_ARM_DMA_USE_IOMMU=y. Since Tegra DRM driver manages IOMMU
> by itself, the devices must be detached from the implicit domain using
> arch-specific IOMMU-API. Note that this works only for arm32 and not for
> arm64, which will remain broken if CONFIG_IOMMU_DMA is enabled.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/gpu/drm/tegra/drm.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)

Applied, thanks.

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-09-26 15:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-19 14:24 [PATCH v1] drm/tegra: Detach devices from IOMMU DMA domain on arm32 Dmitry Osipenko
2018-08-19 14:24 ` [PATCH v1] gpu: host1x: Detach Host1x " Dmitry Osipenko
2018-08-20 17:35   ` kbuild test robot
2018-09-26 15:24 ` [PATCH v1] drm/tegra: Detach devices " Thierry Reding

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.