Skip to content

Commit fe25deb

Browse files
committed
drm/ttm, drm/vmwgfx: Relax permission checking when opening surfaces
Previously, when a surface was opened using a legacy (non prime) handle, it was verified to have been created by a client in the same master realm. Relax this so that opening is also allowed recursively if the client already has the surface open. This works around a regression in svga mesa where opening of a shared surface is used recursively to obtain surface information. Cc: <[email protected]> Signed-off-by: Thomas Hellstrom <[email protected]> Reviewed-by: Sinclair Yeh <[email protected]>
1 parent 6377406 commit fe25deb

File tree

5 files changed

+24
-23
lines changed

5 files changed

+24
-23
lines changed

drivers/gpu/drm/ttm/ttm_object.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile,
179179
if (unlikely(ret != 0))
180180
goto out_err0;
181181

182-
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
182+
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
183183
if (unlikely(ret != 0))
184184
goto out_err1;
185185

@@ -318,7 +318,8 @@ EXPORT_SYMBOL(ttm_ref_object_exists);
318318

319319
int ttm_ref_object_add(struct ttm_object_file *tfile,
320320
struct ttm_base_object *base,
321-
enum ttm_ref_type ref_type, bool *existed)
321+
enum ttm_ref_type ref_type, bool *existed,
322+
bool require_existed)
322323
{
323324
struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
324325
struct ttm_ref_object *ref;
@@ -345,6 +346,9 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
345346
}
346347

347348
rcu_read_unlock();
349+
if (require_existed)
350+
return -EPERM;
351+
348352
ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
349353
false, false);
350354
if (unlikely(ret != 0))
@@ -635,7 +639,7 @@ int ttm_prime_fd_to_handle(struct ttm_object_file *tfile,
635639
prime = (struct ttm_prime_object *) dma_buf->priv;
636640
base = &prime->base;
637641
*handle = base->hash.key;
638-
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
642+
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
639643

640644
dma_buf_put(dma_buf);
641645

drivers/gpu/drm/vmwgfx/vmwgfx_fence.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,10 +1075,8 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
10751075
(void) vmw_fence_obj_reference(fence);
10761076

10771077
if (user_fence_rep != NULL) {
1078-
bool existed;
1079-
1080-
ret = ttm_ref_object_add(tfile, base,
1081-
TTM_REF_USAGE, &existed);
1078+
ret = ttm_ref_object_add(vmw_fp->tfile, base,
1079+
TTM_REF_USAGE, NULL, false);
10821080
if (unlikely(ret != 0)) {
10831081
DRM_ERROR("Failed to reference a fence "
10841082
"object.\n");

drivers/gpu/drm/vmwgfx/vmwgfx_resource.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo,
589589
return ret;
590590

591591
ret = ttm_ref_object_add(tfile, &user_bo->prime.base,
592-
TTM_REF_SYNCCPU_WRITE, &existed);
592+
TTM_REF_SYNCCPU_WRITE, &existed, false);
593593
if (ret != 0 || existed)
594594
ttm_bo_synccpu_write_release(&user_bo->dma.base);
595595

@@ -773,7 +773,7 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile,
773773

774774
*handle = user_bo->prime.base.hash.key;
775775
return ttm_ref_object_add(tfile, &user_bo->prime.base,
776-
TTM_REF_USAGE, NULL);
776+
TTM_REF_USAGE, NULL, false);
777777
}
778778

779779
/*

drivers/gpu/drm/vmwgfx/vmwgfx_surface.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -891,17 +891,16 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
891891
uint32_t handle;
892892
struct ttm_base_object *base;
893893
int ret;
894+
bool require_exist = false;
894895

895896
if (handle_type == DRM_VMW_HANDLE_PRIME) {
896897
ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
897898
if (unlikely(ret != 0))
898899
return ret;
899900
} else {
900-
if (unlikely(drm_is_render_client(file_priv))) {
901-
DRM_ERROR("Render client refused legacy "
902-
"surface reference.\n");
903-
return -EACCES;
904-
}
901+
if (unlikely(drm_is_render_client(file_priv)))
902+
require_exist = true;
903+
905904
if (ACCESS_ONCE(vmw_fpriv(file_priv)->locked_master)) {
906905
DRM_ERROR("Locked master refused legacy "
907906
"surface reference.\n");
@@ -929,17 +928,14 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
929928

930929
/*
931930
* Make sure the surface creator has the same
932-
* authenticating master.
931+
* authenticating master, or is already registered with us.
933932
*/
934933
if (drm_is_primary_client(file_priv) &&
935-
user_srf->master != file_priv->master) {
936-
DRM_ERROR("Trying to reference surface outside of"
937-
" master domain.\n");
938-
ret = -EACCES;
939-
goto out_bad_resource;
940-
}
934+
user_srf->master != file_priv->master)
935+
require_exist = true;
941936

942-
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
937+
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL,
938+
require_exist);
943939
if (unlikely(ret != 0)) {
944940
DRM_ERROR("Could not add a reference to a surface.\n");
945941
goto out_bad_resource;

include/drm/ttm/ttm_object.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base);
229229
* @ref_type: The type of reference.
230230
* @existed: Upon completion, indicates that an identical reference object
231231
* already existed, and the refcount was upped on that object instead.
232+
* @require_existed: Fail with -EPERM if an identical ref object didn't
233+
* already exist.
232234
*
233235
* Checks that the base object is shareable and adds a ref object to it.
234236
*
@@ -243,7 +245,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base);
243245
*/
244246
extern int ttm_ref_object_add(struct ttm_object_file *tfile,
245247
struct ttm_base_object *base,
246-
enum ttm_ref_type ref_type, bool *existed);
248+
enum ttm_ref_type ref_type, bool *existed,
249+
bool require_existed);
247250

248251
extern bool ttm_ref_object_exists(struct ttm_object_file *tfile,
249252
struct ttm_base_object *base);

0 commit comments

Comments
 (0)