[RFC PATCH 2/2] drm/rockchip: Map imported buffers from DMA addresses
Karl Mehltretter
kmehltretter at gmail.com
Thu Oct 8 17:21:14 PDT 2026
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 at cknow-tech.com>
Link: https://lore.kernel.org/r/DLR74W1U9YPC.375IK0HOYHDIG@cknow-tech.com/
Link: https://lore.kernel.org/r/DLYLA3WQNN3X.3FB9MO8ZWBQ5@cknow-tech.com/
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter at gmail.com>
---
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
More information about the linux-arm-kernel
mailing list