Skip to content

Commit

Permalink
drm/i915: Force the slow path after a user-write error
Browse files Browse the repository at this point in the history
If we fail to write the user relocation back when it is changed, force
ourselves to take the slow relocation path where we can handle faults in
the write path. There is still an element of dubiousness as having
patched up the batch to use the correct offset, it no longer matches the
presumed_offset in the relocation, so a second pass may miss any changes
in layout.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180903083337.13134-3-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Sep 3, 2018
1 parent aae7c06 commit fddcd00
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions drivers/gpu/drm/i915/i915_gem_execbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1491,8 +1491,10 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct i915_vma *vma)
* can read from this userspace address.
*/
offset = gen8_canonical_addr(offset & ~UPDATE);
__put_user(offset,
&urelocs[r-stack].presumed_offset);
if (unlikely(__put_user(offset, &urelocs[r-stack].presumed_offset))) {
remain = -EFAULT;
goto out;
}
}
} while (r++, --count);
urelocs += ARRAY_SIZE(stack);
Expand Down Expand Up @@ -1577,7 +1579,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb)

relocs = kvmalloc_array(size, 1, GFP_KERNEL);
if (!relocs) {
kvfree(relocs);
err = -ENOMEM;
goto err;
}
Expand All @@ -1591,6 +1592,7 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb)
if (__copy_from_user((char *)relocs + copied,
(char __user *)urelocs + copied,
len)) {
end_user:
kvfree(relocs);
err = -EFAULT;
goto err;
Expand All @@ -1614,7 +1616,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb)
unsafe_put_user(-1,
&urelocs[copied].presumed_offset,
end_user);
end_user:
user_access_end();

eb->exec[i].relocs_ptr = (uintptr_t)relocs;
Expand Down

0 comments on commit fddcd00

Please sign in to comment.