All of lore.kernel.org
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: Andy Lutomirski <luto@kernel.org>
Cc: David Laight <David.Laight@aculab.com>,
	Ingo Molnar <mingo@kernel.org>, Al Viro <viro@zeniv.linux.org.uk>,
	Thomas Gleixner <tglx@linutronix.de>, X86 ML <x86@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Borislav Petkov <bp@alien8.de>
Subject: Re: [RFC][PATCH 01/22] x86 user stack frame reads: switch to explicit __get_user()
Date: Sun, 29 Mar 2020 15:06:18 -0700	[thread overview]
Message-ID: <CAHk-=wi74U0VLhHLBUqRPrPgercnAdt_8cJ_vjwcTeMzEwocnw@mail.gmail.com> (raw)
In-Reply-To: <CALCETrXWKE8RMX-mZ=p5T19sfS8Rn+1b_EtJz4TXbmf57_aY5g@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1941 bytes --]

On Sun, Mar 29, 2020 at 2:22 PM Andy Lutomirski <luto@kernel.org> wrote:
>
> On Sun, Mar 29, 2020 at 11:16 AM Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
> > But that magical asm-goto-with-outputs patch probably won't land
> > upstream for a couple of years.
>
> I'm not that familiar with gcc politics, but what's the delay?

No, I mean that _my_ magical patch for the kernel won't land upstream,
simply because even if both gcc and clang supported it today, nobody
would effectively have those compilers for a couple of years..

> ISTM
> having an actual upstream Linux asm-goto-with-outputs that works on
> clang might help light a fire under some butts and/or convince someone
> to pay a gcc developer to implement it on gcc.

Yes, but even for clang, it needs a version that isn't even released yet.

And right now my patch is unconditional. It started out that way
because the whole x86 uaccess.h files were such a mess, and I couldn't
be bothered to fix all the small cases to then have *two* cases (one
for asm goto with outputs, one without).

These days my patch is much simpler (thanks to Al's simplifications),
and I think making it handle both cases would likely not be too
painful.

And in that case I might just commit it, even if effectively nobody
has the clang version installed to make use of it.

Anyway, just in case people want to see it, I'm attaching my current
unconditional patch.

Note that it requires Al's uaccess cleanups, but I do want to point
out how it actually makes for simpler code:

 arch/x86/include/asm/uaccess.h | 72 +++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 40 deletions(-)

and not only does it delete more lines than it adds, the lines it adds
are shorter and simpler than the ones it deletes.

But that "deletes more lines than it adds" is only because it doesn't
even try to build without that "asm goto with outputs" support..

            Linus

[-- Attachment #2: patch.diff --]
[-- Type: text/x-patch, Size: 4489 bytes --]


    Use "asm goto" with outputs for clang testing
---
 arch/x86/include/asm/uaccess.h | 72 +++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 40 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index c8247a84244b..9e8b04d4560a 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -279,65 +279,52 @@ do {									\
 } while (0)
 
 #ifdef CONFIG_X86_32
-#define __get_user_asm_u64(x, ptr, retval, errret)			\
+#define __get_user_asm_u64(x, ptr, label)				\
 ({									\
 	__typeof__(ptr) __ptr = (ptr);					\
-	asm volatile("\n"					\
-		     "1:	movl %2,%%eax\n"			\
-		     "2:	movl %3,%%edx\n"			\
-		     "3:\n"				\
-		     ".section .fixup,\"ax\"\n"				\
-		     "4:	mov %4,%0\n"				\
-		     "	xorl %%eax,%%eax\n"				\
-		     "	xorl %%edx,%%edx\n"				\
-		     "	jmp 3b\n"					\
-		     ".previous\n"					\
-		     _ASM_EXTABLE_UA(1b, 4b)				\
-		     _ASM_EXTABLE_UA(2b, 4b)				\
-		     : "=r" (retval), "=&A"(x)				\
-		     : "m" (__m(__ptr)), "m" __m(((u32 __user *)(__ptr)) + 1),	\
-		       "i" (errret), "0" (retval));			\
+	asm_volatile_goto("\n"						\
+		     "1:	movl %1,%%eax\n"			\
+		     "2:	movl %2,%%edx\n"			\
+		     _ASM_EXTABLE_UA(1b, %l3)				\
+		     _ASM_EXTABLE_UA(2b, %l3)				\
+		     : "=&A"(x)						\
+		     : "m" (__m(__ptr)), "m" __m(((u32 __user *)(__ptr)) + 1)	\
+		     : : label);					\
 })
 
 #else
-#define __get_user_asm_u64(x, ptr, retval, errret) \
-	 __get_user_asm(x, ptr, retval, "q", "", "=r", errret)
+#define __get_user_asm_u64(x, ptr, label) \
+	 __get_user_asm(x, ptr, "q", "", "=r", label)
 #endif
 
-#define __get_user_size(x, ptr, size, retval, errret)			\
+#define __get_user_size(x, ptr, size, label)				\
 do {									\
-	retval = 0;							\
 	__chk_user_ptr(ptr);						\
 	switch (size) {							\
 	case 1:								\
-		__get_user_asm(x, ptr, retval, "b", "b", "=q", errret);	\
+		__get_user_asm(x, ptr, "b", "b", "=q", label);		\
 		break;							\
 	case 2:								\
-		__get_user_asm(x, ptr, retval, "w", "w", "=r", errret);	\
+		__get_user_asm(x, ptr, "w", "w", "=r", label);		\
 		break;							\
 	case 4:								\
-		__get_user_asm(x, ptr, retval, "l", "k", "=r", errret);	\
+		__get_user_asm(x, ptr, "l", "k", "=r", label);		\
 		break;							\
 	case 8:								\
-		__get_user_asm_u64(x, ptr, retval, errret);		\
+		__get_user_asm_u64(x, ptr, label);			\
 		break;							\
 	default:							\
 		(x) = __get_user_bad();					\
 	}								\
 } while (0)
 
-#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
-	asm volatile("\n"						\
-		     "1:	mov"itype" %2,%"rtype"1\n"		\
-		     "2:\n"						\
-		     ".section .fixup,\"ax\"\n"				\
-		     "3:	mov %3,%0\n"				\
-		     "	xor"itype" %"rtype"1,%"rtype"1\n"		\
-		     "	jmp 2b\n"					\
-		     ".previous\n"					\
-		     _ASM_EXTABLE_UA(1b, 3b)				\
-		     : "=r" (err), ltype(x)				\
-		     : "m" (__m(addr)), "i" (errret), "0" (err))
+#define __get_user_asm(x, addr, itype, rtype, ltype, label)		\
+	asm_volatile_goto("\n"						\
+		     "1:	mov"itype" %1,%"rtype"0\n"		\
+		     _ASM_EXTABLE_UA(1b, %l2)				\
+		     : ltype(x)						\
+		     : "m" (__m(addr))					\
+		     : : label)
 
 #define __put_user_nocheck(x, ptr, size)			\
 ({								\
@@ -356,14 +343,21 @@ __pu_label:							\
 
 #define __get_user_nocheck(x, ptr, size)				\
 ({									\
+	__label__ __gu_label;						\
 	int __gu_err;							\
 	__inttype(*(ptr)) __gu_val;					\
 	__typeof__(ptr) __gu_ptr = (ptr);				\
 	__typeof__(size) __gu_size = (size);				\
 	__uaccess_begin_nospec();					\
-	__get_user_size(__gu_val, __gu_ptr, __gu_size, __gu_err, -EFAULT);	\
+	__get_user_size(__gu_val, __gu_ptr, __gu_size, __gu_label);	\
 	__uaccess_end();						\
 	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
+	__gu_err = 0;							\
+	if (0) {							\
+__gu_label:								\
+		__uaccess_end();					\
+		__gu_err = -EFAULT;					\
+	}								\
 	__builtin_expect(__gu_err, 0);					\
 })
 
@@ -494,11 +488,9 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt
 
 #define unsafe_get_user(x, ptr, err_label)					\
 do {										\
-	int __gu_err;								\
 	__inttype(*(ptr)) __gu_val;						\
-	__get_user_size(__gu_val, (ptr), sizeof(*(ptr)), __gu_err, -EFAULT);	\
+	__get_user_size(__gu_val, (ptr), sizeof(*(ptr)), err_label);		\
 	(x) = (__force __typeof__(*(ptr)))__gu_val;				\
-	if (unlikely(__gu_err)) goto err_label;					\
 } while (0)
 
 /*

  reply	other threads:[~2020-03-29 22:06 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-23 18:36 [RFC][PATCHSET] x86 uaccess cleanups Al Viro
2020-03-23 18:37 ` [RFC][PATCH 01/22] x86 user stack frame reads: switch to explicit __get_user() Al Viro
2020-03-23 18:37   ` [RFC][PATCH 02/22] x86 kvm page table walks: " Al Viro
2020-03-23 18:38   ` [RFC][PATCH 03/22] x86: switch sigframe sigset handling to explict __get_user()/__put_user() Al Viro
2020-03-23 18:38   ` [RFC][PATCH 04/22] x86: get rid of small constant size cases in raw_copy_{to,from}_user() Al Viro
2020-03-23 18:38   ` [RFC][PATCH 05/22] vm86: get rid of get_user_ex() use Al Viro
2020-03-23 18:38   ` [RFC][PATCH 06/22] x86: get rid of get_user_ex() in ia32_restore_sigcontext() Al Viro
2020-03-23 18:38   ` [RFC][PATCH 07/22] x86: get rid of get_user_ex() in restore_sigcontext() Al Viro
2020-03-23 18:38   ` [RFC][PATCH 08/22] x86: kill get_user_{try,catch,ex} Al Viro
2020-03-23 18:38   ` [RFC][PATCH 09/22] x86: switch save_v86_state() to unsafe_put_user() Al Viro
2020-03-23 18:38   ` [RFC][PATCH 10/22] x86: switch setup_sigcontext() " Al Viro
2020-03-23 18:38   ` [RFC][PATCH 11/22] x86: switch ia32_setup_sigcontext() " Al Viro
2020-03-23 18:38   ` [RFC][PATCH 12/22] x86: get rid of put_user_try in {ia32,x32}_setup_rt_frame() Al Viro
2020-03-23 18:38   ` [RFC][PATCH 13/22] x86: ia32_setup_sigcontext(): lift user_access_{begin,end}() into the callers Al Viro
2020-03-23 18:53     ` Linus Torvalds
2020-03-23 21:42       ` Al Viro
2020-03-23 18:38   ` [RFC][PATCH 14/22] x86: ia32_setup_frame(): consolidate uaccess areas Al Viro
2020-03-23 18:38   ` [RFC][PATCH 15/22] x86: ia32_setup_rt_frame(): " Al Viro
2020-03-23 18:38   ` [RFC][PATCH 16/22] x86: get rid of put_user_try in __setup_rt_frame() (both 32bit and 64bit) Al Viro
2020-03-23 18:38   ` [RFC][PATCH 17/22] x86: setup_sigcontext(): list user_access_{begin,end}() into callers Al Viro
2020-03-23 18:56     ` Linus Torvalds
2020-03-23 18:38   ` [RFC][PATCH 18/22] x86: __setup_frame(): consolidate uaccess areas Al Viro
2020-03-23 18:38   ` [RFC][PATCH 19/22] x86: __setup_rt_frame(): " Al Viro
2020-03-23 18:38   ` [RFC][PATCH 20/22] x86: x32_setup_rt_frame(): " Al Viro
2020-03-23 18:38   ` [RFC][PATCH 21/22] x86: unsafe_put_... macros for sigcontext and sigmask Al Viro
2020-03-23 18:38   ` [RFC][PATCH 22/22] kill uaccess_try() Al Viro
2020-03-24 15:15   ` [RFC][PATCH 01/22] x86 user stack frame reads: switch to explicit __get_user() Peter Zijlstra
2020-03-28 10:48   ` Ingo Molnar
2020-03-28 11:59     ` Al Viro
2020-03-29  9:26       ` Ingo Molnar
2020-03-29 16:50         ` Andy Lutomirski
2020-03-29 17:05           ` Linus Torvalds
2020-03-29 17:41           ` David Laight
2020-03-29 17:56             ` Linus Torvalds
2020-03-29 18:03               ` David Laight
2020-03-29 18:16                 ` Linus Torvalds
2020-03-29 18:32                   ` David Laight
2020-03-29 18:55                     ` Linus Torvalds
2020-03-29 21:21                   ` Andy Lutomirski
2020-03-29 22:06                     ` Linus Torvalds [this message]
2020-03-29 22:12                       ` Linus Torvalds
2020-03-29 18:16               ` Al Viro
2020-03-29 18:19                 ` Linus Torvalds
2020-03-29 17:57         ` Al Viro
2020-03-30 15:54           ` David Laight
2020-03-23 19:16 ` [RFC][PATCHSET] x86 uaccess cleanups Linus Torvalds
2020-03-27  2:24 ` [RFC][PATCHSET v2] " Al Viro
2020-03-27  2:26   ` Al Viro
2020-03-27  2:30     ` Al Viro
2020-03-27  2:31       ` [RFC][PATCH v2 01/22] x86 user stack frame reads: switch to explicit __get_user() Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 02/22] x86 kvm page table walks: " Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 03/22] x86: switch sigframe sigset handling to explict __get_user()/__put_user() Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 04/22] x86: get rid of small constant size cases in raw_copy_{to,from}_user() Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 05/22] vm86: get rid of get_user_ex() use Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 06/22] x86: get rid of get_user_ex() in ia32_restore_sigcontext() Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 07/22] x86: get rid of get_user_ex() in restore_sigcontext() Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 08/22] x86: kill get_user_{try,catch,ex} Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 09/22] x86: switch save_v86_state() to unsafe_put_user() Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 10/22] x86: switch setup_sigcontext() " Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 11/22] x86: switch ia32_setup_sigcontext() " Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 12/22] x86: get rid of put_user_try in {ia32,x32}_setup_rt_frame() Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 13/22] x86: ia32_setup_sigcontext(): lift user_access_{begin,end}() into the callers Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 14/22] x86: ia32_setup_frame(): consolidate uaccess areas Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 15/22] x86: ia32_setup_rt_frame(): " Al Viro
2020-03-27  2:31         ` [RFC][PATCH v2 16/22] x86: get rid of put_user_try in __setup_rt_frame() (both 32bit and 64bit) Al Viro
2020-03-27  2:32         ` [RFC][PATCH v2 17/22] x86: setup_sigcontext(): list user_access_{begin,end}() into callers Al Viro
2020-03-27  2:32         ` [RFC][PATCH v2 18/22] x86: __setup_frame(): consolidate uaccess areas Al Viro
2020-03-27  2:32         ` [RFC][PATCH v2 19/22] x86: __setup_rt_frame(): " Al Viro
2020-03-27  2:32         ` [RFC][PATCH v2 20/22] x86: x32_setup_rt_frame(): " Al Viro
2020-03-27  2:32         ` [RFC][PATCH v2 21/22] x86: unsafe_put-style macro for sigmask Al Viro
2020-03-27  2:32         ` [RFC][PATCH v2 22/22] kill uaccess_try() Al Viro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAHk-=wi74U0VLhHLBUqRPrPgercnAdt_8cJ_vjwcTeMzEwocnw@mail.gmail.com' \
    --to=torvalds@linux-foundation.org \
    --cc=David.Laight@aculab.com \
    --cc=bp@alien8.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=viro@zeniv.linux.org.uk \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.