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 <[email protected]> Link: https://lore.kernel.org/r/[email protected]/ Link: https://lore.kernel.org/r/[email protected]/ Assisted-by: LLM Signed-off-by: Karl Mehltretter <[email protected]> --- 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
