diff options
author | Dave Airlie <airlied@redhat.com> | 2020-09-17 05:54:24 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2020-09-17 23:14:00 +0300 |
commit | 0b988ca1c7c4c73983b4ea96ef7c2af2263c87eb (patch) | |
tree | 729ee7adfc399e41f03a768f1a1df8f036d7af88 /drivers/gpu/drm/vmwgfx | |
parent | 67d6a8b358eac488112a4775f77dc3dbf63bea88 (diff) | |
download | linux-0b988ca1c7c4c73983b4ea96ef7c2af2263c87eb.tar.xz |
drm/ttm: protect against reentrant bind in the drivers
This moves the generic tracking into the drivers and protects
against reentrancy in the drivers. It fixes up radeon and agp
to be able to query the bound status as that is required.
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200917043040.146575-2-airlied@gmail.com
Diffstat (limited to 'drivers/gpu/drm/vmwgfx')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index 3458c5c3531d..01146b27c9a1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -267,6 +267,7 @@ struct vmw_ttm_tt { struct vmw_sg_table vsgt; uint64_t sg_alloc_size; bool mapped; + bool bound; }; const size_t vmw_tt_size = sizeof(struct vmw_ttm_tt); @@ -565,7 +566,13 @@ static int vmw_ttm_bind(struct ttm_bo_device *bdev, { struct vmw_ttm_tt *vmw_be = container_of(ttm, struct vmw_ttm_tt, dma_ttm.ttm); - int ret; + int ret = 0; + + if (!bo_mem) + return -EINVAL; + + if (vmw_be->bound) + return 0; ret = vmw_ttm_map_dma(vmw_be); if (unlikely(ret != 0)) @@ -576,8 +583,9 @@ static int vmw_ttm_bind(struct ttm_bo_device *bdev, switch (bo_mem->mem_type) { case VMW_PL_GMR: - return vmw_gmr_bind(vmw_be->dev_priv, &vmw_be->vsgt, + ret = vmw_gmr_bind(vmw_be->dev_priv, &vmw_be->vsgt, ttm->num_pages, vmw_be->gmr_id); + break; case VMW_PL_MOB: if (unlikely(vmw_be->mob == NULL)) { vmw_be->mob = @@ -586,13 +594,15 @@ static int vmw_ttm_bind(struct ttm_bo_device *bdev, return -ENOMEM; } - return vmw_mob_bind(vmw_be->dev_priv, vmw_be->mob, + ret = vmw_mob_bind(vmw_be->dev_priv, vmw_be->mob, &vmw_be->vsgt, ttm->num_pages, vmw_be->gmr_id); + break; default: BUG(); } - return 0; + vmw_be->bound = true; + return ret; } static void vmw_ttm_unbind(struct ttm_bo_device *bdev, @@ -601,6 +611,9 @@ static void vmw_ttm_unbind(struct ttm_bo_device *bdev, struct vmw_ttm_tt *vmw_be = container_of(ttm, struct vmw_ttm_tt, dma_ttm.ttm); + if (!vmw_be->bound) + return; + switch (vmw_be->mem_type) { case VMW_PL_GMR: vmw_gmr_unbind(vmw_be->dev_priv, vmw_be->gmr_id); @@ -614,6 +627,7 @@ static void vmw_ttm_unbind(struct ttm_bo_device *bdev, if (vmw_be->dev_priv->map_mode == vmw_dma_map_bind) vmw_ttm_unmap_dma(vmw_be); + vmw_be->bound = false; } |