Lu Baolu
2024-Aug-12 07:10 UTC
[PATCH 1/3] drm/nouveau/tegra: Use iommu_paging_domain_alloc()
In nvkm_device_tegra_probe_iommu(), a paging domain is allocated for @dev
and attached to it on success. Use iommu_paging_domain_alloc() to make it
explicit.
Signed-off-by: Lu Baolu <baolu.lu at linux.intel.com>
Link: https://lore.kernel.org/r/20240610085555.88197-7-baolu.lu at
linux.intel.com
---
drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
index 87caa4a72921..763c4c2925f9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
@@ -120,8 +120,8 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra
*tdev)
mutex_init(&tdev->iommu.mutex);
if (device_iommu_mapped(dev)) {
- tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type);
- if (!tdev->iommu.domain)
+ tdev->iommu.domain = iommu_paging_domain_alloc(dev);
+ if (IS_ERR(tdev->iommu.domain))
goto error;
/*
--
2.34.1
Commit <421be3ee36a4> ("drm/rockchip: Refactor IOMMU
initialisation") has
refactored rockchip_drm_init_iommu() to pass a device that the domain is
allocated for. Replace iommu_domain_alloc() with
iommu_paging_domain_alloc() to retire the former.
Signed-off-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Link: https://lore.kernel.org/r/20240610085555.88197-19-baolu.lu at
linux.intel.com
---
drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 44d769d9234d..11e5d10de4d7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -103,13 +103,17 @@ static int rockchip_drm_init_iommu(struct drm_device
*drm_dev)
struct rockchip_drm_private *private = drm_dev->dev_private;
struct iommu_domain_geometry *geometry;
u64 start, end;
+ int ret;
if (IS_ERR_OR_NULL(private->iommu_dev))
return 0;
- private->domain = iommu_domain_alloc(private->iommu_dev->bus);
- if (!private->domain)
- return -ENOMEM;
+ private->domain = iommu_paging_domain_alloc(private->iommu_dev);
+ if (IS_ERR(private->domain)) {
+ ret = PTR_ERR(private->domain);
+ private->domain = NULL;
+ return ret;
+ }
geometry = &private->domain->geometry;
start = geometry->aperture_start;
--
2.34.1
Commit <17de3f5fdd35> ("iommu: Retire bus ops") removes iommu
ops from
the bus structure. The iommu subsystem no longer relies on bus for
operations. So iommu_domain_alloc() interface is no longer relevant.
Normally, iommu_paging_domain_alloc() could be a replacement for
iommu_domain_alloc() if the caller has the right device for IOMMU API
use. Unfortunately, this is not the case for this driver.
Iterate the devices on the platform bus and find a suitable device
whose device DMA is translated by an IOMMU. Then use this device to
allocate an iommu domain. The iommu subsystem prevents domains
allocated by one iommu driver from being attached to devices managed
by any different iommu driver.
Signed-off-by: Lu Baolu <baolu.lu at linux.intel.com>
Link: https://lore.kernel.org/r/20240610085555.88197-20-baolu.lu at
linux.intel.com
---
drivers/gpu/drm/tegra/drm.c | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 03d1c76aec2d..ee391f859992 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1133,6 +1133,17 @@ static bool host1x_drm_wants_iommu(struct host1x_device
*dev)
return domain != NULL;
}
+static int iommu_mapped_device(struct device *dev, void *data)
+{
+ struct device **iommu_dev = data;
+
+ if (!device_iommu_mapped(dev))
+ return 0;
+
+ *iommu_dev = dev;
+ return 1;
+}
+
static int host1x_drm_probe(struct host1x_device *dev)
{
struct tegra_drm *tegra;
@@ -1149,16 +1160,21 @@ static int host1x_drm_probe(struct host1x_device *dev)
goto put;
}
- if (host1x_drm_wants_iommu(dev) &&
iommu_present(&platform_bus_type)) {
- tegra->domain = iommu_domain_alloc(&platform_bus_type);
- if (!tegra->domain) {
- err = -ENOMEM;
- goto free;
+ if (host1x_drm_wants_iommu(dev)) {
+ struct device *iommu_dev = NULL;
+
+ bus_for_each_dev(&platform_bus_type, NULL, &iommu_dev,
iommu_mapped_device);
+ if (iommu_dev) {
+ tegra->domain = iommu_paging_domain_alloc(iommu_dev);
+ if (IS_ERR(tegra->domain)) {
+ err = PTR_ERR(tegra->domain);
+ goto free;
+ }
+
+ err = iova_cache_get();
+ if (err < 0)
+ goto domain;
}
-
- err = iova_cache_get();
- if (err < 0)
- goto domain;
}
mutex_init(&tegra->clients_lock);
--
2.34.1
Reasonably Related Threads
- [PATCH v2 0/3] drm: Use iommu_paging_domain_alloc()
- [PATCH v2 1/3] drm/nouveau/tegra: Use iommu_paging_domain_alloc()
- [PATCH v2 1/3] drm/nouveau/tegra: Use iommu_paging_domain_alloc()
- [PATCH v2 00/33] iommu: Move iommu_group setup to IOMMU core code
- [PATCH v2 00/33] iommu: Move iommu_group setup to IOMMU core code