diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 74 |
1 files changed, 24 insertions, 50 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c index 0a4c340252ec..265f7c48d856 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c @@ -27,30 +27,44 @@ #include "vmwgfx_drv.h" -static struct ttm_buffer_object *vmw_bo_vm_lookup(struct ttm_device *bdev, - unsigned long offset, - unsigned long pages) +static int vmw_bo_vm_lookup(struct ttm_device *bdev, + struct drm_file *filp, + unsigned long offset, + unsigned long pages, + struct ttm_buffer_object **p_bo) { struct vmw_private *dev_priv = container_of(bdev, struct vmw_private, bdev); struct drm_device *drm = &dev_priv->drm; struct drm_vma_offset_node *node; - struct ttm_buffer_object *bo = NULL; + int ret; + + *p_bo = NULL; drm_vma_offset_lock_lookup(bdev->vma_manager); node = drm_vma_offset_lookup_locked(bdev->vma_manager, offset, pages); if (likely(node)) { - bo = container_of(node, struct ttm_buffer_object, + *p_bo = container_of(node, struct ttm_buffer_object, base.vma_node); - bo = ttm_bo_get_unless_zero(bo); + *p_bo = ttm_bo_get_unless_zero(*p_bo); } drm_vma_offset_unlock_lookup(bdev->vma_manager); - if (!bo) + if (!*p_bo) { drm_err(drm, "Could not find buffer object to map\n"); + return -EINVAL; + } + + if (!drm_vma_node_is_allowed(node, filp)) { + ret = -EACCES; + goto out_no_access; + } - return bo; + return 0; +out_no_access: + ttm_bo_put(*p_bo); + return ret; } int vmw_mmap(struct file *filp, struct vm_area_struct *vma) @@ -64,7 +78,6 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma) }; struct drm_file *file_priv = filp->private_data; struct vmw_private *dev_priv = vmw_priv(file_priv->minor->dev); - struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; struct ttm_device *bdev = &dev_priv->bdev; struct ttm_buffer_object *bo; int ret; @@ -72,13 +85,9 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma) if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET_START)) return -EINVAL; - bo = vmw_bo_vm_lookup(bdev, vma->vm_pgoff, vma_pages(vma)); - if (unlikely(!bo)) - return -EINVAL; - - ret = vmw_user_bo_verify_access(bo, tfile); + ret = vmw_bo_vm_lookup(bdev, file_priv, vma->vm_pgoff, vma_pages(vma), &bo); if (unlikely(ret != 0)) - goto out_unref; + return ret; ret = ttm_bo_mmap_obj(vma, bo); if (unlikely(ret != 0)) @@ -99,38 +108,3 @@ out_unref: return ret; } -/* struct vmw_validation_mem callback */ -static int vmw_vmt_reserve(struct vmw_validation_mem *m, size_t size) -{ - static struct ttm_operation_ctx ctx = {.interruptible = false, - .no_wait_gpu = false}; - struct vmw_private *dev_priv = container_of(m, struct vmw_private, vvm); - - return ttm_mem_global_alloc(vmw_mem_glob(dev_priv), size, &ctx); -} - -/* struct vmw_validation_mem callback */ -static void vmw_vmt_unreserve(struct vmw_validation_mem *m, size_t size) -{ - struct vmw_private *dev_priv = container_of(m, struct vmw_private, vvm); - - return ttm_mem_global_free(vmw_mem_glob(dev_priv), size); -} - -/** - * vmw_validation_mem_init_ttm - Interface the validation memory tracker - * to ttm. - * @dev_priv: Pointer to struct vmw_private. The reason we choose a vmw private - * rather than a struct vmw_validation_mem is to make sure assumption in the - * callbacks that struct vmw_private derives from struct vmw_validation_mem - * holds true. - * @gran: The recommended allocation granularity - */ -void vmw_validation_mem_init_ttm(struct vmw_private *dev_priv, size_t gran) -{ - struct vmw_validation_mem *vvm = &dev_priv->vvm; - - vvm->reserve_mem = vmw_vmt_reserve; - vvm->unreserve_mem = vmw_vmt_unreserve; - vvm->gran = gran; -} |