aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2017-03-27 05:21:25 -0400
committerThomas Hellstrom <thellstrom@vmware.com>2017-03-30 05:43:39 -0400
commitfe25deb7737ce6c0879ccf79c99fa1221d428bf2 (patch)
tree8e5091f95dc74616cb5aab8560f8a0b7d1b8e577
parent63774069d9527a1aeaa4aa20e929ef5e8e9ecc38 (diff)
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: <stable@vger.kernel.org> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com>
-rw-r--r--drivers/gpu/drm/ttm/ttm_object.c10
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_surface.c22
-rw-r--r--include/drm/ttm/ttm_object.h5
5 files changed, 24 insertions, 23 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c
index fdb451e3ec01..d750140bafbc 100644
--- a/drivers/gpu/drm/ttm/ttm_object.c
+++ b/drivers/gpu/drm/ttm/ttm_object.c
@@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile,
179 if (unlikely(ret != 0)) 179 if (unlikely(ret != 0))
180 goto out_err0; 180 goto out_err0;
181 181
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);
183 if (unlikely(ret != 0)) 183 if (unlikely(ret != 0))
184 goto out_err1; 184 goto out_err1;
185 185
@@ -318,7 +318,8 @@ EXPORT_SYMBOL(ttm_ref_object_exists);
318 318
319int ttm_ref_object_add(struct ttm_object_file *tfile, 319int ttm_ref_object_add(struct ttm_object_file *tfile,
320 struct ttm_base_object *base, 320 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)
322{ 323{
323 struct drm_open_hash *ht = &tfile->ref_hash[ref_type]; 324 struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
324 struct ttm_ref_object *ref; 325 struct ttm_ref_object *ref;
@@ -345,6 +346,9 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
345 } 346 }
346 347
347 rcu_read_unlock(); 348 rcu_read_unlock();
349 if (require_existed)
350 return -EPERM;
351
348 ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref), 352 ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
349 false, false); 353 false, false);
350 if (unlikely(ret != 0)) 354 if (unlikely(ret != 0))
@@ -635,7 +639,7 @@ int ttm_prime_fd_to_handle(struct ttm_object_file *tfile,
635 prime = (struct ttm_prime_object *) dma_buf->priv; 639 prime = (struct ttm_prime_object *) dma_buf->priv;
636 base = &prime->base; 640 base = &prime->base;
637 *handle = base->hash.key; 641 *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);
639 643
640 dma_buf_put(dma_buf); 644 dma_buf_put(dma_buf);
641 645
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index 4076063e0fdd..6b2708b4eafe 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -1075,10 +1075,8 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
1075 (void) vmw_fence_obj_reference(fence); 1075 (void) vmw_fence_obj_reference(fence);
1076 1076
1077 if (user_fence_rep != NULL) { 1077 if (user_fence_rep != NULL) {
1078 bool existed; 1078 ret = ttm_ref_object_add(vmw_fp->tfile, base,
1079 1079 TTM_REF_USAGE, NULL, false);
1080 ret = ttm_ref_object_add(tfile, base,
1081 TTM_REF_USAGE, &existed);
1082 if (unlikely(ret != 0)) { 1080 if (unlikely(ret != 0)) {
1083 DRM_ERROR("Failed to reference a fence " 1081 DRM_ERROR("Failed to reference a fence "
1084 "object.\n"); 1082 "object.\n");
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 65b3f0369636..bf23153d4f55 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -589,7 +589,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo,
589 return ret; 589 return ret;
590 590
591 ret = ttm_ref_object_add(tfile, &user_bo->prime.base, 591 ret = ttm_ref_object_add(tfile, &user_bo->prime.base,
592 TTM_REF_SYNCCPU_WRITE, &existed); 592 TTM_REF_SYNCCPU_WRITE, &existed, false);
593 if (ret != 0 || existed) 593 if (ret != 0 || existed)
594 ttm_bo_synccpu_write_release(&user_bo->dma.base); 594 ttm_bo_synccpu_write_release(&user_bo->dma.base);
595 595
@@ -773,7 +773,7 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile,
773 773
774 *handle = user_bo->prime.base.hash.key; 774 *handle = user_bo->prime.base.hash.key;
775 return ttm_ref_object_add(tfile, &user_bo->prime.base, 775 return ttm_ref_object_add(tfile, &user_bo->prime.base,
776 TTM_REF_USAGE, NULL); 776 TTM_REF_USAGE, NULL, false);
777} 777}
778 778
779/* 779/*
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index f410502cb075..adc023fe67f3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -891,17 +891,16 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
891 uint32_t handle; 891 uint32_t handle;
892 struct ttm_base_object *base; 892 struct ttm_base_object *base;
893 int ret; 893 int ret;
894 bool require_exist = false;
894 895
895 if (handle_type == DRM_VMW_HANDLE_PRIME) { 896 if (handle_type == DRM_VMW_HANDLE_PRIME) {
896 ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle); 897 ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
897 if (unlikely(ret != 0)) 898 if (unlikely(ret != 0))
898 return ret; 899 return ret;
899 } else { 900 } else {
900 if (unlikely(drm_is_render_client(file_priv))) { 901 if (unlikely(drm_is_render_client(file_priv)))
901 DRM_ERROR("Render client refused legacy " 902 require_exist = true;
902 "surface reference.\n"); 903
903 return -EACCES;
904 }
905 if (ACCESS_ONCE(vmw_fpriv(file_priv)->locked_master)) { 904 if (ACCESS_ONCE(vmw_fpriv(file_priv)->locked_master)) {
906 DRM_ERROR("Locked master refused legacy " 905 DRM_ERROR("Locked master refused legacy "
907 "surface reference.\n"); 906 "surface reference.\n");
@@ -929,17 +928,14 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
929 928
930 /* 929 /*
931 * Make sure the surface creator has the same 930 * Make sure the surface creator has the same
932 * authenticating master. 931 * authenticating master, or is already registered with us.
933 */ 932 */
934 if (drm_is_primary_client(file_priv) && 933 if (drm_is_primary_client(file_priv) &&
935 user_srf->master != file_priv->master) { 934 user_srf->master != file_priv->master)
936 DRM_ERROR("Trying to reference surface outside of" 935 require_exist = true;
937 " master domain.\n");
938 ret = -EACCES;
939 goto out_bad_resource;
940 }
941 936
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);
943 if (unlikely(ret != 0)) { 939 if (unlikely(ret != 0)) {
944 DRM_ERROR("Could not add a reference to a surface.\n"); 940 DRM_ERROR("Could not add a reference to a surface.\n");
945 goto out_bad_resource; 941 goto out_bad_resource;
diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h
index ed953f98f0e1..1487011fe057 100644
--- a/include/drm/ttm/ttm_object.h
+++ b/include/drm/ttm/ttm_object.h
@@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base);
229 * @ref_type: The type of reference. 229 * @ref_type: The type of reference.
230 * @existed: Upon completion, indicates that an identical reference object 230 * @existed: Upon completion, indicates that an identical reference object
231 * already existed, and the refcount was upped on that object instead. 231 * 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.
232 * 234 *
233 * Checks that the base object is shareable and adds a ref object to it. 235 * Checks that the base object is shareable and adds a ref object to it.
234 * 236 *
@@ -243,7 +245,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base);
243 */ 245 */
244extern int ttm_ref_object_add(struct ttm_object_file *tfile, 246extern int ttm_ref_object_add(struct ttm_object_file *tfile,
245 struct ttm_base_object *base, 247 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);
247 250
248extern bool ttm_ref_object_exists(struct ttm_object_file *tfile, 251extern bool ttm_ref_object_exists(struct ttm_object_file *tfile,
249 struct ttm_base_object *base); 252 struct ttm_base_object *base);