This keeps MMIO_REMAP fixed for its whole lifetime. Other buffers (VRAM/GTT) are unchanged.
This change pins it when we export the dma-buf. If the export fails, we undo the pin. When the dma-buf is released, we unpin it. MMIO_REMAP (HDP flush page) is a hardware I/O window, not normal RAM. It should never be moved Cc: Christian König <christian.koe...@amd.com> Cc: Alex Deucher <alexander.deuc...@amd.com> Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmu...@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 36 +++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index f85e16be438f..31d78561ab95 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -47,6 +47,7 @@ #include <linux/scatterlist.h> #include <linux/slab.h> +static void amdgpu_dmabuf_release(struct dma_buf *dmabuf); static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops; /** @@ -377,13 +378,27 @@ const struct dma_buf_ops amdgpu_dmabuf_ops = { .unpin = amdgpu_dma_buf_unpin, .map_dma_buf = amdgpu_dma_buf_map, .unmap_dma_buf = amdgpu_dma_buf_unmap, - .release = drm_gem_dmabuf_release, + .release = amdgpu_dmabuf_release, .begin_cpu_access = amdgpu_dma_buf_begin_cpu_access, .mmap = drm_gem_dmabuf_mmap, .vmap = drm_gem_dmabuf_vmap, .vunmap = drm_gem_dmabuf_vunmap, }; +/* Drop the export-time pin for MMIO_REMAP when the dma-buf is finally released. */ +static void amdgpu_dmabuf_release(struct dma_buf *dmabuf) +{ + struct drm_gem_object *gobj = dmabuf->priv; + struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); + + if (bo && bo->tbo.resource && + bo->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP) + amdgpu_bo_unpin(bo); + + drm_gem_dmabuf_release(dmabuf); +} + + /** * amdgpu_gem_prime_export - &drm_driver.gem_prime_export implementation * @gobj: GEM BO @@ -399,15 +414,30 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj, { struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); struct dma_buf *buf; + int r; if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) || bo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) return ERR_PTR(-EPERM); + /* MMIO_REMAP: opt-in + pin at export so later paths never migrate it */ + if (bo->tbo.resource && + bo->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP) { + r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); + if (r) + return ERR_PTR(r); + } + buf = drm_gem_prime_export(gobj, flags); - if (!IS_ERR(buf)) - buf->ops = &amdgpu_dmabuf_ops; + if (IS_ERR(buf)) { + /* if export failed, drop the pin we took */ + if (bo->tbo.resource && + bo->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP) + amdgpu_bo_unpin(bo); + return buf; + } + buf->ops = &amdgpu_dmabuf_ops; return buf; } -- 2.34.1