Skip to content

Commit aba07b9

Browse files
committed
drm/vmwgfx: Prevent unmapping active read buffers
The kms paths keep a persistent map active to read and compare the cursor buffer. These maps can race with each other in simple scenario where: a) buffer "a" mapped for update b) buffer "a" mapped for compare c) do the compare d) unmap "a" for compare e) update the cursor f) unmap "a" for update At step "e" the buffer has been unmapped and the read contents is bogus. Prevent unmapping of active read buffers by simply keeping a count of how many paths have currently active maps and unmap only when the count reaches 0. Fixes: 485d98d ("drm/vmwgfx: Add support for CursorMob and CursorBypass 4") Cc: Broadcom internal kernel review list <[email protected]> Cc: [email protected] Cc: <[email protected]> # v5.19+ Signed-off-by: Zack Rusin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Martin Krastev <[email protected]> Reviewed-by: Maaz Mombasawala <[email protected]>
1 parent c358a80 commit aba07b9

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

drivers/gpu/drm/vmwgfx/vmwgfx_bo.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ void *vmw_bo_map_and_cache_size(struct vmw_bo *vbo, size_t size)
360360
void *virtual;
361361
int ret;
362362

363+
atomic_inc(&vbo->map_count);
364+
363365
virtual = ttm_kmap_obj_virtual(&vbo->map, &not_used);
364366
if (virtual)
365367
return virtual;
@@ -383,11 +385,17 @@ void *vmw_bo_map_and_cache_size(struct vmw_bo *vbo, size_t size)
383385
*/
384386
void vmw_bo_unmap(struct vmw_bo *vbo)
385387
{
388+
int map_count;
389+
386390
if (vbo->map.bo == NULL)
387391
return;
388392

389-
ttm_bo_kunmap(&vbo->map);
390-
vbo->map.bo = NULL;
393+
map_count = atomic_dec_return(&vbo->map_count);
394+
395+
if (!map_count) {
396+
ttm_bo_kunmap(&vbo->map);
397+
vbo->map.bo = NULL;
398+
}
391399
}
392400

393401

@@ -421,6 +429,7 @@ static int vmw_bo_init(struct vmw_private *dev_priv,
421429
vmw_bo->tbo.priority = 3;
422430
vmw_bo->res_tree = RB_ROOT;
423431
xa_init(&vmw_bo->detached_resources);
432+
atomic_set(&vmw_bo->map_count, 0);
424433

425434
params->size = ALIGN(params->size, PAGE_SIZE);
426435
drm_gem_private_object_init(vdev, &vmw_bo->tbo.base, params->size);

drivers/gpu/drm/vmwgfx/vmwgfx_bo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ struct vmw_bo_params {
7171
* @map: Kmap object for semi-persistent mappings
7272
* @res_tree: RB tree of resources using this buffer object as a backing MOB
7373
* @res_prios: Eviction priority counts for attached resources
74+
* @map_count: The number of currently active maps. Will differ from the
75+
* cpu_writers because it includes kernel maps.
7476
* @cpu_writers: Number of synccpu write grabs. Protected by reservation when
7577
* increased. May be decreased without reservation.
7678
* @dx_query_ctx: DX context if this buffer object is used as a DX query MOB
@@ -90,6 +92,7 @@ struct vmw_bo {
9092
u32 res_prios[TTM_MAX_BO_PRIORITY];
9193
struct xarray detached_resources;
9294

95+
atomic_t map_count;
9396
atomic_t cpu_writers;
9497
/* Not ref-counted. Protected by binding_mutex */
9598
struct vmw_resource *dx_query_ctx;

0 commit comments

Comments
 (0)