aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index d6a994a07393..26d08bb58218 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -539,6 +539,8 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
539 total = 0; 539 total = 0;
540 for (i = 0; i < count; i++) { 540 for (i = 0; i < count; i++) {
541 struct drm_i915_gem_relocation_entry __user *user_relocs; 541 struct drm_i915_gem_relocation_entry __user *user_relocs;
542 u64 invalid_offset = (u64)-1;
543 int j;
542 544
543 user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr; 545 user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr;
544 546
@@ -549,6 +551,25 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
549 goto err; 551 goto err;
550 } 552 }
551 553
554 /* As we do not update the known relocation offsets after
555 * relocating (due to the complexities in lock handling),
556 * we need to mark them as invalid now so that we force the
557 * relocation processing next time. Just in case the target
558 * object is evicted and then rebound into its old
559 * presumed_offset before the next execbuffer - if that
560 * happened we would make the mistake of assuming that the
561 * relocations were valid.
562 */
563 for (j = 0; j < exec[i].relocation_count; j++) {
564 if (copy_to_user(&user_relocs[j].presumed_offset,
565 &invalid_offset,
566 sizeof(invalid_offset))) {
567 ret = -EFAULT;
568 mutex_lock(&dev->struct_mutex);
569 goto err;
570 }
571 }
572
552 reloc_offset[i] = total; 573 reloc_offset[i] = total;
553 total += exec[i].relocation_count; 574 total += exec[i].relocation_count;
554 } 575 }