* [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.