diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-01-19 19:26:56 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-01-21 10:32:00 +0000 |
commit | 1fcdaa7e72a7666a8367cabd77db092992357328 (patch) | |
tree | 593815424051c79fe2eb543ba7b3158445d2fe19 /drivers/gpu/drm | |
parent | befedbb7e24935e149640ddfc2b82dab42985e3c (diff) |
drm/i915: Reject vma creation larger than address space
Disallow creation of a vma that is larger than the available address
space, or triggers an overflow on fence expansion.
Testcase: igt/gem_exec_reloc/gtt-32
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170119192659.31789-3-chris@chris-wilson.co.uk
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_vma.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 635f2635b1f2..e58d8799bee2 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -77,7 +77,7 @@ vma_create(struct drm_i915_gem_object *obj, struct rb_node *rb, **p; int i; - vma = kmem_cache_zalloc(to_i915(obj->base.dev)->vmas, GFP_KERNEL); + vma = kmem_cache_zalloc(vm->i915->vmas, GFP_KERNEL); if (vma == NULL) return ERR_PTR(-ENOMEM); @@ -85,7 +85,6 @@ vma_create(struct drm_i915_gem_object *obj, for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) init_request_active(&vma->last_read[i], i915_vma_retire); init_request_active(&vma->last_fence, NULL); - list_add(&vma->vm_link, &vm->unbound_list); vma->vm = vm; vma->obj = obj; vma->size = obj->base.size; @@ -107,11 +106,20 @@ vma_create(struct drm_i915_gem_object *obj, } } + if (unlikely(vma->size > vm->total)) + goto err_vma; + if (i915_is_ggtt(vm)) { - GEM_BUG_ON(overflows_type(vma->size, u32)); + if (unlikely(overflows_type(vma->size, u32))) + goto err_vma; + vma->fence_size = i915_gem_fence_size(vm->i915, vma->size, i915_gem_object_get_tiling(obj), i915_gem_object_get_stride(obj)); + if (unlikely(vma->fence_size < vma->size || /* overflow */ + vma->fence_size > vm->total)) + goto err_vma; + GEM_BUG_ON(!IS_ALIGNED(vma->fence_size, I915_GTT_MIN_ALIGNMENT)); vma->fence_alignment = i915_gem_fence_alignment(vm->i915, vma->size, @@ -140,8 +148,13 @@ vma_create(struct drm_i915_gem_object *obj, } rb_link_node(&vma->obj_node, rb, p); rb_insert_color(&vma->obj_node, &obj->vma_tree); + list_add(&vma->vm_link, &vm->unbound_list); return vma; + +err_vma: + kmem_cache_free(vm->i915->vmas, vma); + return ERR_PTR(-E2BIG); } static struct i915_vma * |