drm: verify vma access in TTM+GEM drivers
authorDavid Herrmann <dh.herrmann@gmail.com>
Sun, 25 Aug 2013 16:28:59 +0000 (18:28 +0200)
committerDave Airlie <airlied@redhat.com>
Tue, 27 Aug 2013 01:54:58 +0000 (11:54 +1000)
GEM does already a good job in tracking access to gem buffers via handles
and drm_vma access management. However, TTM drivers currently do not
verify this during mmap().

TTM provides the verify_access() callback to test this. So fix all drivers
to actually call into gem+vma to verify access instead of always returning
0.

All drivers assume that user-space can only get access to TTM buffers via
GEM handles. So whenever the verify_access() callback is called from
ttm_bo_mmap(), the buffer must have a valid embedded gem object. This is
true for all TTM+GEM drivers. But that's why this patch doesn't touch pure
TTM drivers (ie, vmwgfx).

v2: Switch to drm_vma_node_verify_access() to correctly return -EACCES if
    access was denied.

Cc: Dave Airlie <airlied@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Cc: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/ast/ast_ttm.c
drivers/gpu/drm/cirrus/cirrus_ttm.c
drivers/gpu/drm/mgag200/mgag200_ttm.c
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/qxl/qxl_ttm.c
drivers/gpu/drm/radeon/radeon_ttm.c

index cf1c833f73cae65ced08fa3ee26e425e582b6f8e..20fcf4ee3af0ac2d72970a623318adfb1b6e3958 100644 (file)
@@ -148,7 +148,9 @@ ast_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
 
 static int ast_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
 {
-       return 0;
+       struct ast_bo *astbo = ast_bo(bo);
+
+       return drm_vma_node_verify_access(&astbo->gem.vma_node, filp);
 }
 
 static int ast_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
index bf8a5066948985eefd6b9d5025d5503b20601432..ae2385cc71cb6e24da13885ed7dea84fe79b7bc6 100644 (file)
@@ -148,7 +148,9 @@ cirrus_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
 
 static int cirrus_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
 {
-       return 0;
+       struct cirrus_bo *cirrusbo = cirrus_bo(bo);
+
+       return drm_vma_node_verify_access(&cirrusbo->gem.vma_node, filp);
 }
 
 static int cirrus_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
index 6cf3fa0b35cc27248425cb78fbf35ab46b2097cc..fd4539d9ad2c6a00f38830be80d9a7fabe9fa604 100644 (file)
@@ -148,7 +148,9 @@ mgag200_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
 
 static int mgag200_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
 {
-       return 0;
+       struct mgag200_bo *mgabo = mgag200_bo(bo);
+
+       return drm_vma_node_verify_access(&mgabo->gem.vma_node, filp);
 }
 
 static int mgag200_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
index 4e7ee5f4155c96bce6b1091fdf432a6d46140eab..e4444bacd0b2b2da14084c895eddbdd1cf9823b4 100644 (file)
@@ -1260,7 +1260,9 @@ out:
 static int
 nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
 {
-       return 0;
+       struct nouveau_bo *nvbo = nouveau_bo(bo);
+
+       return drm_vma_node_verify_access(&nvbo->gem->vma_node, filp);
 }
 
 static int
index 1dfd84cda2a128e39f4e8143c43b3d0c6a99f30b..037786d7c1dc882d89d73d544460182fdf0df0cf 100644 (file)
@@ -212,7 +212,9 @@ static void qxl_evict_flags(struct ttm_buffer_object *bo,
 
 static int qxl_verify_access(struct ttm_buffer_object *bo, struct file *filp)
 {
-       return 0;
+       struct qxl_bo *qbo = to_qxl_bo(bo);
+
+       return drm_vma_node_verify_access(&qbo->gem_base.vma_node, filp);
 }
 
 static int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
index 6c0ce8915fac9efc399654a8b25e4bd180285d0a..71245d6f34a20c0f64a6eff3057eb6d7ae37f388 100644 (file)
@@ -203,7 +203,9 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo,
 
 static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp)
 {
-       return 0;
+       struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo);
+
+       return drm_vma_node_verify_access(&rbo->gem_base.vma_node, filp);
 }
 
 static void radeon_move_null(struct ttm_buffer_object *bo,