提交 7e6c8a93 编写于 作者: C Chris Wilson 提交者: Joseph Qi

drm/i915: Force the slow path after a user-write error

commit fddcd00a49e9122a3579247151e9cb3ce5a1a36e upstream.

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: NChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: NJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180903083337.13134-3-chris@chris-wilson.co.ukSigned-off-by: NShile Zhang <shile.zhang@linux.alibaba.com>
Acked-by: NJoseph Qi <joseph.qi@linux.alibaba.com>
上级 8e823df5
...@@ -1484,8 +1484,10 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct i915_vma *vma) ...@@ -1484,8 +1484,10 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct i915_vma *vma)
* can read from this userspace address. * can read from this userspace address.
*/ */
offset = gen8_canonical_addr(offset & ~UPDATE); offset = gen8_canonical_addr(offset & ~UPDATE);
__put_user(offset, if (unlikely(__put_user(offset, &urelocs[r-stack].presumed_offset))) {
&urelocs[r-stack].presumed_offset); remain = -EFAULT;
goto out;
}
} }
} while (r++, --count); } while (r++, --count);
urelocs += ARRAY_SIZE(stack); urelocs += ARRAY_SIZE(stack);
...@@ -1570,7 +1572,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) ...@@ -1570,7 +1572,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb)
relocs = kvmalloc_array(size, 1, GFP_KERNEL); relocs = kvmalloc_array(size, 1, GFP_KERNEL);
if (!relocs) { if (!relocs) {
kvfree(relocs);
err = -ENOMEM; err = -ENOMEM;
goto err; goto err;
} }
...@@ -1584,6 +1585,7 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) ...@@ -1584,6 +1585,7 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb)
if (__copy_from_user((char *)relocs + copied, if (__copy_from_user((char *)relocs + copied,
(char __user *)urelocs + copied, (char __user *)urelocs + copied,
len)) { len)) {
end_user:
kvfree(relocs); kvfree(relocs);
err = -EFAULT; err = -EFAULT;
goto err; goto err;
...@@ -1607,7 +1609,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) ...@@ -1607,7 +1609,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb)
unsafe_put_user(-1, unsafe_put_user(-1,
&urelocs[copied].presumed_offset, &urelocs[copied].presumed_offset,
end_user); end_user);
end_user:
user_access_end(); user_access_end();
eb->exec[i].relocs_ptr = (uintptr_t)relocs; eb->exec[i].relocs_ptr = (uintptr_t)relocs;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册