On Fri, Mar 01, 2019 at 11:34:52AM +0100, Peter Zijlstra wrote: > Let me do an allmodconfig build to see how much pain is caused by that > redundant CLAC warning.
arch/x86/lib/usercopy_64.o: warning: objtool: .altinstr_replacement+0x30: redundant UACCESS disable drivers/gpu/drm/i915/i915_gem_execbuffer.o: warning: objtool: .altinstr_replacement+0x22: redundant UACCESS disable drivers/gpu/drm/i915/i915_gem_execbuffer.o: warning: objtool: .altinstr_replacement+0x64: redundant UACCESS disable drivers/xen/privcmd.o: warning: objtool: privcmd_ioctl()+0x1c0: call to {dynamic}() with UACCESS enabled The usercopy one is difficult, that's copy_user_handle_tail(), it is buggered though, because that lacks notrace and thus has a __fentry__ call in. Also, afaict all exception jumps into copy_user_handle_tail() will have AC=1, but the __{get,put}_user_nocheck() things do STAC/CLAC all over again. So what do we do? Annotate that we start with AC=1 and then immediately do the clac, and then let __{get,put}_user_nocheck() do their own thing? or make it use the unsafe stuff? --- diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index ee42bb0cbeb3..e1ab9a50937c 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c @@ -59,7 +59,7 @@ EXPORT_SYMBOL(clear_user); * Since protection fault in copy_from/to_user is not a normal situation, * it is not necessary to optimize tail handling. */ -__visible unsigned long +__visible notrace unsigned long copy_user_handle_tail(char *to, char *from, unsigned len) { for (; len; --len, to++) { diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 485b259127c3..695212c5bd07 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1606,6 +1606,7 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) len)) { end_user: user_access_end(); +end: kvfree(relocs); err = -EFAULT; goto err; @@ -1625,7 +1626,7 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) * relocations were valid. */ if (!user_access_begin(urelocs, size)) - goto end_user; + goto end; for (copied = 0; copied < nreloc; copied++) unsafe_put_user(-1, @@ -2616,7 +2617,7 @@ i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data, * when we did the "copy_from_user()" above. */ if (!user_access_begin(user_exec_list, count * sizeof(*user_exec_list))) - goto end_user; + goto end; for (i = 0; i < args->buffer_count; i++) { if (!(exec2_list[i].offset & UPDATE)) @@ -2630,6 +2631,7 @@ i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data, } end_user: user_access_end(); +end:; } args->flags &= ~__I915_EXEC_UNKNOWN_FLAGS;