[RFC PATCH 2/2] drm/rockchip: Map imported buffers from DMA addresses

From: Karl Mehltretter

Date: Thu Oct 08 2026 - 20:23:00 EST


rockchip_gem_prime_import_sg_table() uses iommu_map_sgtable(), which reads
CPU-side pages and lengths. DMABUF_DEBUG clears these fields, causing
the RK3588 import failures reported by Diederik de Haas.

The attachment's DMA addresses belong to the VOP's default domain,
while scanout uses a separate DRM domain. Use iommu_map_sgtable_dma()
to copy the live mapping into that domain.

Keep native allocations unchanged. Unsupported imports still use the
old page-based path and remain unfixed under strict DMABUF_DEBUG.
This RFC retains reverse translation rather than sharing the DMA domain.

Reported-by: Diederik de Haas <diederik@xxxxxxxxxxxxxx>
Link: https://lore.kernel.org/r/DLR74W1U9YPC.375IK0HOYHDIG@xxxxxxxxxxxxxx/
Link: https://lore.kernel.org/r/DLYLA3WQNN3X.3FB9MO8ZWBQ5@xxxxxxxxxxxxxx/
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@xxxxxxxxx>
---
drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 9a1dc9f12072..501c94cb921a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -20,7 +20,8 @@
#include "rockchip_drm_drv.h"
#include "rockchip_drm_gem.h"

-static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
+static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj,
+ struct device *dma_dev)
{
struct drm_device *drm = rk_obj->base.dev;
struct rockchip_drm_private *private = drm->dev_private;
@@ -40,8 +41,16 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)

rk_obj->dma_addr = rk_obj->mm.start;

- ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt,
- prot);
+ if (dma_dev) {
+ ret = iommu_map_sgtable_dma(private->domain, rk_obj->dma_addr,
+ dma_dev, rk_obj->sgt, prot);
+ if (ret == -EOPNOTSUPP)
+ ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr,
+ rk_obj->sgt, prot);
+ } else {
+ ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr,
+ rk_obj->sgt, prot);
+ }
if (ret < (ssize_t)rk_obj->base.size) {
DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
ret, rk_obj->base.size);
@@ -131,7 +140,7 @@ static int rockchip_gem_alloc_iommu(struct rockchip_gem_object *rk_obj,
if (ret < 0)
return ret;

- ret = rockchip_gem_iommu_map(rk_obj);
+ ret = rockchip_gem_iommu_map(rk_obj, NULL);
if (ret < 0)
goto err_free;

@@ -457,7 +466,7 @@ rockchip_gem_iommu_map_sg(struct drm_device *drm,
struct rockchip_gem_object *rk_obj)
{
rk_obj->sgt = sg;
- return rockchip_gem_iommu_map(rk_obj);
+ return rockchip_gem_iommu_map(rk_obj, attach->dev);
}

static int
--
2.53.0