From 81bfa3ab6e69d89e99d69aebb5b3c09790a4a9ee Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 14 May 2014 19:35:17 +0100 Subject: [PATCH] drm/i915: DON'T LOOK I warned you. --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index e94aa36..d0587c7 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -272,6 +272,9 @@ relocate_entry_cpu(struct drm_i915_gem_object *obj, char *vaddr; int ret; + if (delta > to_i915(dev)->gtt.base.total) + return -EFAULT; + ret = i915_gem_object_set_to_cpu_domain(obj, true); if (ret) return ret; @@ -309,6 +312,9 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, void __iomem *reloc_page; int ret; + if (delta > to_i915(dev)->gtt.base.total) + return -EFAULT; + ret = i915_gem_object_set_to_gtt_domain(obj, true); if (ret) return ret; @@ -702,6 +708,43 @@ err: } static int +i915_gem_execbuffer_relocate_check_slow(struct i915_vma *vma, + struct eb_vmas *eb, + struct drm_i915_gem_relocation_entry *relocs) +{ + struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; + int32_t min = ~0 >> 1; + int i, ret; + + for (i = 0; i < entry->relocation_count; i++) { + struct drm_i915_gem_relocation_entry *reloc = &reloc[i]; + if ((int32_t)reloc->delta < min) + min = (int32_t)reloc->delta; + } + if (min < 0) { + struct drm_i915_gem_object *obj = vma->obj; + + if (drm_mm_node_allocated(&vma->node) && + vma->node.start + min > to_i915(obj->base.dev)->gtt.base.total) { + ret = i915_vma_unbind(vma); + if (ret) + return ret; + } + if (!drm_mm_node_allocated(&vma->node)) { + if (entry->alignment == 0) + entry->alignment = i915_gem_get_gtt_alignment(obj->base.dev, + obj->base.size, + obj->tiling_mode, + true); + while (entry->alignment < -min) + entry->alignment <<= 1; + } + } + + return 0; +} + +static int i915_gem_execbuffer_relocate_slow(struct drm_device *dev, struct drm_i915_gem_execbuffer2 *args, struct drm_file *file, @@ -792,6 +835,14 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, if (ret) goto err; + list_for_each_entry(vma, &eb->vmas, exec_list) { + int offset = vma->exec_entry - exec; + ret = i915_gem_execbuffer_relocate_check_slow(vma, eb, + reloc + reloc_offset[offset]); + if (ret) + goto err; + } + need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, &need_relocs); if (ret) -- 1.7.9.5