From 1fcdaa7e72a7666a8367cabd77db092992357328 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 19 Jan 2017 19:26:56 +0000 Subject: [PATCH] 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 Cc: Joonas Lahtinen Cc: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/20170119192659.31789-3-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_vma.c | 19 ++++++++++++++++--- 1 file 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 * -- 2.20.1