linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86_32: add support for 64 bit __get_user()
@ 2016-03-09 17:22 Benjamin LaHaise
  2016-03-09 17:36 ` H. Peter Anvin
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Benjamin LaHaise @ 2016-03-09 17:22 UTC (permalink / raw)
  To: Ingo Molnar, Russell King
  Cc: Thomas Gleixner, H. Peter Anvin, x86, linux-kernel

The existing __get_user() implementation does not support fetching
64 bit values on 32 bit x86.  Implement this in a way that does not 
generate any incorrect warnings as cautioned by Russell King.  Test 
code available at http://www.kvack.org/~bcrl/x86_32-get_user.tar .  

Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index a4a30e4..2d0607a 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -333,7 +333,23 @@ do {									\
 } while (0)
 
 #ifdef CONFIG_X86_32
-#define __get_user_asm_u64(x, ptr, retval, errret)	(x) = __get_user_bad()
+#define __get_user_asm_u64(x, addr, err, errret)			\
+	asm volatile(ASM_STAC "\n"					\
+		     "1:	movl %2,%%eax\n"			\
+		     "2:	movl %3,%%edx\n"			\
+		     "3: " ASM_CLAC "\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(1b, 4b)				\
+		     _ASM_EXTABLE(2b, 4b)				\
+		     : "=r" (err), "=A"(x)				\
+		     : "m" (__m(addr)), "m" __m(((u32 *)(addr)) + 1),	\
+		       "i" (errret), "0" (err))
+
 #define __get_user_asm_ex_u64(x, ptr)			(x) = __get_user_bad()
 #else
 #define __get_user_asm_u64(x, ptr, retval, errret) \
@@ -420,11 +436,20 @@ do {									\
 #define __get_user_nocheck(x, ptr, size)				\
 ({									\
 	int __gu_err;							\
-	unsigned long __gu_val;						\
-	__uaccess_begin();						\
-	__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);	\
-	__uaccess_end();						\
-	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
+	if (size == 8) {						\
+		unsigned long __gu_val[2];				\
+		__gu_err = 0;						\
+		__uaccess_begin();					\
+		__get_user_asm_u64(__gu_val, ptr, __gu_err, -EFAULT);	\
+		__uaccess_end();					\
+		(x) = *(__force __typeof__((ptr)))__gu_val;		\
+	} else {							\
+		unsigned long __gu_val;					\
+		__uaccess_begin();					\
+		__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
+		__uaccess_end();					\
+		(x) = (__force __typeof__(*(ptr)))__gu_val;		\
+	}								\
 	__builtin_expect(__gu_err, 0);					\
 })
 
-- 
"Thought is the essence of where you are now."

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user()
  2016-03-09 17:22 [PATCH] x86_32: add support for 64 bit __get_user() Benjamin LaHaise
@ 2016-03-09 17:36 ` H. Peter Anvin
  2016-03-09 17:50   ` Benjamin LaHaise
  2016-03-09 18:17 ` [PATCH] x86_32: add support for 64 bit __get_user() kbuild test robot
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: H. Peter Anvin @ 2016-03-09 17:36 UTC (permalink / raw)
  To: Benjamin LaHaise, Ingo Molnar, Russell King
  Cc: Thomas Gleixner, x86, linux-kernel

On March 9, 2016 9:22:25 AM PST, Benjamin LaHaise <bcrl@kvack.org> wrote:
>The existing __get_user() implementation does not support fetching
>64 bit values on 32 bit x86.  Implement this in a way that does not 
>generate any incorrect warnings as cautioned by Russell King.  Test 
>code available at http://www.kvack.org/~bcrl/x86_32-get_user.tar .  
>
>Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
>
>diff --git a/arch/x86/include/asm/uaccess.h
>b/arch/x86/include/asm/uaccess.h
>index a4a30e4..2d0607a 100644
>--- a/arch/x86/include/asm/uaccess.h
>+++ b/arch/x86/include/asm/uaccess.h
>@@ -333,7 +333,23 @@ do {									\
> } while (0)
> 
> #ifdef CONFIG_X86_32
>-#define __get_user_asm_u64(x, ptr, retval, errret)	(x) =
>__get_user_bad()
>+#define __get_user_asm_u64(x, addr, err, errret)			\
>+	asm volatile(ASM_STAC "\n"					\
>+		     "1:	movl %2,%%eax\n"			\
>+		     "2:	movl %3,%%edx\n"			\
>+		     "3: " ASM_CLAC "\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(1b, 4b)				\
>+		     _ASM_EXTABLE(2b, 4b)				\
>+		     : "=r" (err), "=A"(x)				\
>+		     : "m" (__m(addr)), "m" __m(((u32 *)(addr)) + 1),	\
>+		       "i" (errret), "0" (err))
>+
> #define __get_user_asm_ex_u64(x, ptr)			(x) = __get_user_bad()
> #else
> #define __get_user_asm_u64(x, ptr, retval, errret) \
>@@ -420,11 +436,20 @@ do {									\
> #define __get_user_nocheck(x, ptr, size)				\
> ({									\
> 	int __gu_err;							\
>-	unsigned long __gu_val;						\
>-	__uaccess_begin();						\
>-	__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);	\
>-	__uaccess_end();						\
>-	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
>+	if (size == 8) {						\
>+		unsigned long __gu_val[2];				\
>+		__gu_err = 0;						\
>+		__uaccess_begin();					\
>+		__get_user_asm_u64(__gu_val, ptr, __gu_err, -EFAULT);	\
>+		__uaccess_end();					\
>+		(x) = *(__force __typeof__((ptr)))__gu_val;		\
>+	} else {							\
>+		unsigned long __gu_val;					\
>+		__uaccess_begin();					\
>+		__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
>+		__uaccess_end();					\
>+		(x) = (__force __typeof__(*(ptr)))__gu_val;		\
>+	}								\
> 	__builtin_expect(__gu_err, 0);					\
> })
> 

Weird.  I could swear we had already fixed this a few years ago.
-- 
Sent from my Android device with K-9 Mail. Please excuse brevity and formatting.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user()
  2016-03-09 17:36 ` H. Peter Anvin
@ 2016-03-09 17:50   ` Benjamin LaHaise
  2016-03-09 18:22     ` H. Peter Anvin
  0 siblings, 1 reply; 14+ messages in thread
From: Benjamin LaHaise @ 2016-03-09 17:50 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Ingo Molnar, Russell King, Thomas Gleixner, x86, linux-kernel

On Wed, Mar 09, 2016 at 09:36:30AM -0800, H. Peter Anvin wrote:
> On March 9, 2016 9:22:25 AM PST, Benjamin LaHaise <bcrl@kvack.org> wrote:
> >The existing __get_user() implementation does not support fetching
> >64 bit values on 32 bit x86.  Implement this in a way that does not 
> >generate any incorrect warnings as cautioned by Russell King.  Test 
> >code available at http://www.kvack.org/~bcrl/x86_32-get_user.tar .  
...
> Weird.  I could swear we had already fixed this a few years ago.

That surprised me as well, but Russell raised the fact that the approaches 
previously tried on 32 bit architectures had caused various incorrect 
compiler warnings for certain obscure cases -- see the code in test_module.c 
in that URL that Russell provided to demonstrate the problem across all the 
corner cases.

		-ben
-- 
"Thought is the essence of where you are now."

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user()
  2016-03-09 17:22 [PATCH] x86_32: add support for 64 bit __get_user() Benjamin LaHaise
  2016-03-09 17:36 ` H. Peter Anvin
@ 2016-03-09 18:17 ` kbuild test robot
  2016-03-09 18:22 ` kbuild test robot
  2016-03-09 18:23 ` kbuild test robot
  3 siblings, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2016-03-09 18:17 UTC (permalink / raw)
  To: Benjamin LaHaise
  Cc: kbuild-all, Ingo Molnar, Russell King, Thomas Gleixner,
	H. Peter Anvin, x86, linux-kernel

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

Hi Benjamin,

[auto build test ERROR on tip/x86/core]
[also build test ERROR on v4.5-rc7 next-20160309]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Benjamin-LaHaise/x86_32-add-support-for-64-bit-__get_user/20160310-012551
config: x86_64-alldefconfig (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   fs/select.c: Assembler messages:
>> fs/select.c:710: Error: operand type mismatch for `movq'
>> fs/select.c:714: Error: incorrect register `%cx' used with `q' suffix
   fs/select.c:711: Error: operand type mismatch for `movq'
>> fs/select.c:715: Error: incorrect register `%si' used with `q' suffix
--
   fs/aio.c: Assembler messages:
>> fs/aio.c:1606: Error: operand type mismatch for `movq'
>> fs/aio.c:1610: Error: incorrect register `%si' used with `q' suffix

vim +710 fs/select.c

9f72949f David Woodhouse   2006-01-18  704  	size_t sigsetsize = 0;
9f72949f David Woodhouse   2006-01-18  705  	sigset_t __user *up = NULL;
9f72949f David Woodhouse   2006-01-18  706  
9f72949f David Woodhouse   2006-01-18  707  	if (sig) {
9f72949f David Woodhouse   2006-01-18  708  		if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t))
e110ab94 Al Viro           2006-02-01  709  		    || __get_user(up, (sigset_t __user * __user *)sig)
9f72949f David Woodhouse   2006-01-18 @710  		    || __get_user(sigsetsize,
e110ab94 Al Viro           2006-02-01  711  				(size_t __user *)(sig+sizeof(void *))))
9f72949f David Woodhouse   2006-01-18  712  			return -EFAULT;
9f72949f David Woodhouse   2006-01-18  713  	}
9f72949f David Woodhouse   2006-01-18 @714  
c9da9f21 Heiko Carstens    2009-01-14 @715  	return do_pselect(n, inp, outp, exp, tsp, up, sigsetsize);
9f72949f David Woodhouse   2006-01-18  716  }
9f72949f David Woodhouse   2006-01-18  717  
5d0e5283 Christoph Hellwig 2010-03-10  718  #ifdef __ARCH_WANT_SYS_OLD_SELECT

:::::: The code at line 710 was first introduced by commit
:::::: 9f72949f679df06021c9e43886c9191494fdb007 [PATCH] Add pselect/ppoll system call implementation

:::::: TO: David Woodhouse <dwmw2@infradead.org>
:::::: CC: Linus Torvalds <torvalds@g5.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 9748 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user()
  2016-03-09 17:22 [PATCH] x86_32: add support for 64 bit __get_user() Benjamin LaHaise
  2016-03-09 17:36 ` H. Peter Anvin
  2016-03-09 18:17 ` [PATCH] x86_32: add support for 64 bit __get_user() kbuild test robot
@ 2016-03-09 18:22 ` kbuild test robot
  2016-03-09 18:23 ` kbuild test robot
  3 siblings, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2016-03-09 18:22 UTC (permalink / raw)
  To: Benjamin LaHaise
  Cc: kbuild-all, Ingo Molnar, Russell King, Thomas Gleixner,
	H. Peter Anvin, x86, linux-kernel

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

Hi Benjamin,

[auto build test ERROR on tip/x86/core]
[also build test ERROR on v4.5-rc7 next-20160309]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Benjamin-LaHaise/x86_32-add-support-for-64-bit-__get_user/20160310-012551
config: x86_64-randconfig-s3-03100205 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   kernel/ptrace.c: Assembler messages:
   kernel/ptrace.c:1039: Error: operand type mismatch for `movq'
>> kernel/ptrace.c:1043: Error: incorrect register `%cx' used with `q' suffix
   kernel/ptrace.c:1040: Error: operand type mismatch for `movq'
   kernel/ptrace.c:1044: Error: incorrect register `%cx' used with `q' suffix

vim +1043 kernel/ptrace.c

9fed81dc Namhyung Kim  2010-10-27  1033  		struct iovec __user *uiov = datavp;
2225a122 Suresh Siddha 2010-02-11  1034  
2225a122 Suresh Siddha 2010-02-11  1035  		if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov)))
2225a122 Suresh Siddha 2010-02-11  1036  			return -EFAULT;
2225a122 Suresh Siddha 2010-02-11  1037  
2225a122 Suresh Siddha 2010-02-11  1038  		if (__get_user(kiov.iov_base, &uiov->iov_base) ||
2225a122 Suresh Siddha 2010-02-11 @1039  		    __get_user(kiov.iov_len, &uiov->iov_len))
2225a122 Suresh Siddha 2010-02-11  1040  			return -EFAULT;
2225a122 Suresh Siddha 2010-02-11  1041  
2225a122 Suresh Siddha 2010-02-11  1042  		ret = ptrace_regset(child, request, addr, &kiov);
2225a122 Suresh Siddha 2010-02-11 @1043  		if (!ret)
2225a122 Suresh Siddha 2010-02-11  1044  			ret = __put_user(kiov.iov_len, &uiov->iov_len);
2225a122 Suresh Siddha 2010-02-11  1045  		break;
2225a122 Suresh Siddha 2010-02-11  1046  	}

:::::: The code at line 1043 was first introduced by commit
:::::: 2225a122ae26d542bdce523d9d87a4a7ba10e07b ptrace: Add support for generic PTRACE_GETREGSET/PTRACE_SETREGSET

:::::: TO: Suresh Siddha <suresh.b.siddha@intel.com>
:::::: CC: H. Peter Anvin <hpa@zytor.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 25154 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user()
  2016-03-09 17:50   ` Benjamin LaHaise
@ 2016-03-09 18:22     ` H. Peter Anvin
  2016-03-09 18:27       ` Benjamin LaHaise
  2016-03-09 19:30       ` [PATCH] x86_32: add support for 64 bit __get_user() v2 Benjamin LaHaise
  0 siblings, 2 replies; 14+ messages in thread
From: H. Peter Anvin @ 2016-03-09 18:22 UTC (permalink / raw)
  To: Benjamin LaHaise
  Cc: Ingo Molnar, Russell King, Thomas Gleixner, x86, linux-kernel

On 03/09/2016 09:50 AM, Benjamin LaHaise wrote:
> On Wed, Mar 09, 2016 at 09:36:30AM -0800, H. Peter Anvin wrote:
>> On March 9, 2016 9:22:25 AM PST, Benjamin LaHaise <bcrl@kvack.org> wrote:
>>> The existing __get_user() implementation does not support fetching
>>> 64 bit values on 32 bit x86.  Implement this in a way that does not 
>>> generate any incorrect warnings as cautioned by Russell King.  Test 
>>> code available at http://www.kvack.org/~bcrl/x86_32-get_user.tar .  
> ...
>> Weird.  I could swear we had already fixed this a few years ago.
> 
> That surprised me as well, but Russell raised the fact that the approaches 
> previously tried on 32 bit architectures had caused various incorrect 
> compiler warnings for certain obscure cases -- see the code in test_module.c 
> in that URL that Russell provided to demonstrate the problem across all the 
> corner cases.

Oh, I see... I implemented it for put but not get... weird.  You may
want to look at the __inttype() macro defined earlier in this file; it
might be useful.

I presume you have already seen:

>> fs/select.c:710: Error: operand type mismatch for `movq'
>> fs/select.c:714: Error: incorrect register `%cx' used with `q' suffix
   fs/select.c:711: Error: operand type mismatch for `movq'
>> fs/select.c:715: Error: incorrect register `%si' used with `q' suffix
--
   fs/aio.c: Assembler messages:
>> fs/aio.c:1606: Error: operand type mismatch for `movq'
>> fs/aio.c:1610: Error: incorrect register `%si' used with `q' suffix

... which implies it used 16-bit registers for 64-bit operations when
compiling for 64 bits.

	-hpa

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user()
  2016-03-09 17:22 [PATCH] x86_32: add support for 64 bit __get_user() Benjamin LaHaise
                   ` (2 preceding siblings ...)
  2016-03-09 18:22 ` kbuild test robot
@ 2016-03-09 18:23 ` kbuild test robot
  3 siblings, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2016-03-09 18:23 UTC (permalink / raw)
  To: Benjamin LaHaise
  Cc: kbuild-all, Ingo Molnar, Russell King, Thomas Gleixner,
	H. Peter Anvin, x86, linux-kernel

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

Hi Benjamin,

[auto build test ERROR on tip/x86/core]
[also build test ERROR on v4.5-rc7 next-20160309]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Benjamin-LaHaise/x86_32-add-support-for-64-bit-__get_user/20160310-012551
config: x86_64-randconfig-s0-03100154 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   arch/x86/kernel/ptrace.c: Assembler messages:
>> arch/x86/kernel/ptrace.c:531: Error: operand type mismatch for `movq'
>> arch/x86/kernel/ptrace.c:535: Error: incorrect register `%dx' used with `q' suffix
--
   In file included from include/linux/thread_info.h:11:0,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/seqlock.h:35,
                    from include/linux/time.h:5,
                    from include/uapi/linux/timex.h:56,
                    from include/linux/timex.h:56,
                    from include/linux/sched.h:19,
                    from fs/select.c:18:
   fs/select.c: In function 'SyS_pselect6':
>> include/linux/bug.h:33:45: error: unsupported operand size for extended register
    #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                                ^
>> include/linux/syscalls.h:108:31: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
    #define __SC_TEST(t, a) (void)BUILD_BUG_ON_ZERO(!__TYPE_IS_LL(t) && sizeof(t) > sizeof(long))
                                  ^
>> include/linux/syscalls.h:93:23: note: in expansion of macro '__SC_TEST'
    #define __MAP1(m,t,a) m(t,a)
                          ^
   include/linux/syscalls.h:94:35: note: in expansion of macro '__MAP1'
    #define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)
                                      ^
   include/linux/syscalls.h:95:35: note: in expansion of macro '__MAP2'
    #define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__)
                                      ^
   include/linux/syscalls.h:96:35: note: in expansion of macro '__MAP3'
    #define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__)
                                      ^
   include/linux/syscalls.h:97:35: note: in expansion of macro '__MAP4'
    #define __MAP5(m,t,a,...) m(t,a), __MAP4(m,__VA_ARGS__)
                                      ^
>> include/linux/syscalls.h:98:35: note: in expansion of macro '__MAP5'
    #define __MAP6(m,t,a,...) m(t,a), __MAP5(m,__VA_ARGS__)
                                      ^
>> include/linux/syscalls.h:99:22: note: in expansion of macro '__MAP6'
    #define __MAP(n,...) __MAP##n(__VA_ARGS__)
                         ^
   include/linux/syscalls.h:202:3: note: in expansion of macro '__MAP'
      __MAP(x,__SC_TEST,__VA_ARGS__);    \
      ^
   include/linux/syscalls.h:191:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^
   include/linux/syscalls.h:187:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
                                       ^
>> fs/select.c:700:1: note: in expansion of macro 'SYSCALL_DEFINE6'
    SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
    ^
>> include/linux/bug.h:33:45: error: unsupported operand size for extended register
    #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                                ^
>> include/linux/syscalls.h:108:31: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
    #define __SC_TEST(t, a) (void)BUILD_BUG_ON_ZERO(!__TYPE_IS_LL(t) && sizeof(t) > sizeof(long))
                                  ^
>> include/linux/syscalls.h:93:23: note: in expansion of macro '__SC_TEST'
    #define __MAP1(m,t,a) m(t,a)
                          ^
   include/linux/syscalls.h:94:35: note: in expansion of macro '__MAP1'
    #define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)
                                      ^
   include/linux/syscalls.h:95:35: note: in expansion of macro '__MAP2'
    #define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__)
                                      ^
   include/linux/syscalls.h:96:35: note: in expansion of macro '__MAP3'
    #define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__)
                                      ^
   include/linux/syscalls.h:97:35: note: in expansion of macro '__MAP4'
    #define __MAP5(m,t,a,...) m(t,a), __MAP4(m,__VA_ARGS__)
                                      ^
>> include/linux/syscalls.h:98:35: note: in expansion of macro '__MAP5'
    #define __MAP6(m,t,a,...) m(t,a), __MAP5(m,__VA_ARGS__)
                                      ^
>> include/linux/syscalls.h:99:22: note: in expansion of macro '__MAP6'
    #define __MAP(n,...) __MAP##n(__VA_ARGS__)
                         ^
   include/linux/syscalls.h:202:3: note: in expansion of macro '__MAP'
      __MAP(x,__SC_TEST,__VA_ARGS__);    \
      ^
   include/linux/syscalls.h:191:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^
   include/linux/syscalls.h:187:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
                                       ^
>> fs/select.c:700:1: note: in expansion of macro 'SYSCALL_DEFINE6'
    SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
    ^
>> include/linux/bug.h:33:45: error: unsupported operand size for extended register
    #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                                ^
>> include/linux/syscalls.h:108:31: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
    #define __SC_TEST(t, a) (void)BUILD_BUG_ON_ZERO(!__TYPE_IS_LL(t) && sizeof(t) > sizeof(long))
                                  ^
>> include/linux/syscalls.h:93:23: note: in expansion of macro '__SC_TEST'
    #define __MAP1(m,t,a) m(t,a)
                          ^
   include/linux/syscalls.h:94:35: note: in expansion of macro '__MAP1'
    #define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)
                                      ^
   include/linux/syscalls.h:95:35: note: in expansion of macro '__MAP2'
    #define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__)
                                      ^
   include/linux/syscalls.h:96:35: note: in expansion of macro '__MAP3'
    #define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__)
                                      ^
   include/linux/syscalls.h:97:35: note: in expansion of macro '__MAP4'
    #define __MAP5(m,t,a,...) m(t,a), __MAP4(m,__VA_ARGS__)
                                      ^
>> include/linux/syscalls.h:98:35: note: in expansion of macro '__MAP5'
    #define __MAP6(m,t,a,...) m(t,a), __MAP5(m,__VA_ARGS__)
                                      ^
>> include/linux/syscalls.h:99:22: note: in expansion of macro '__MAP6'
    #define __MAP(n,...) __MAP##n(__VA_ARGS__)
                         ^
   include/linux/syscalls.h:202:3: note: in expansion of macro '__MAP'
      __MAP(x,__SC_TEST,__VA_ARGS__);    \
      ^
   include/linux/syscalls.h:191:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^
   include/linux/syscalls.h:187:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
                                       ^
>> fs/select.c:700:1: note: in expansion of macro 'SYSCALL_DEFINE6'
    SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
    ^
>> include/linux/bug.h:33:45: error: unsupported operand size for extended register
    #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                                ^
>> include/linux/syscalls.h:108:31: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
    #define __SC_TEST(t, a) (void)BUILD_BUG_ON_ZERO(!__TYPE_IS_LL(t) && sizeof(t) > sizeof(long))
                                  ^
--
   fs/compat.c: In function 'compat_SyS_fcntl64':
>> fs/compat.c:417:1: error: unsupported operand size for extended register
    COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
    ^
>> fs/compat.c:417:1: error: unsupported operand size for extended register
>> fs/compat.c:417:1: error: unsupported operand size for extended register
>> fs/compat.c:417:1: error: unsupported operand size for extended register
>> fs/compat.c:417:1: error: unsupported operand size for extended register
>> fs/compat.c:417:1: error: unsupported operand size for extended register
--
   kernel/ptrace.c: In function 'ptrace_request':
>> kernel/ptrace.c:1058:1: error: unsupported operand size for extended register
    }
    ^
>> kernel/ptrace.c:1058:1: error: unsupported operand size for extended register
>> kernel/ptrace.c:1058:1: error: unsupported operand size for extended register
>> kernel/ptrace.c:1058:1: error: unsupported operand size for extended register
>> kernel/ptrace.c:1058:1: error: unsupported operand size for extended register
>> kernel/ptrace.c:1058:1: error: unsupported operand size for extended register
--
   kernel/signal.c: In function 'do_sigaltstack':
>> kernel/signal.c:3154:1: error: unsupported operand size for extended register
    }
    ^
>> kernel/signal.c:3154:1: error: unsupported operand size for extended register
>> kernel/signal.c:3154:1: error: unsupported operand size for extended register
>> kernel/signal.c:3154:1: error: unsupported operand size for extended register
>> kernel/signal.c:3154:1: error: unsupported operand size for extended register
>> kernel/signal.c:3154:1: error: unsupported operand size for extended register
--
   net/socket.c: In function 'copy_msghdr_from_user':
>> net/socket.c:1873:1: error: unsupported operand size for extended register
    }
    ^
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register
>> net/socket.c:1873:1: error: unsupported operand size for extended register

vim +531 arch/x86/kernel/ptrace.c

91e7b707 Roland McGrath 2008-01-30  525  		}
91e7b707 Roland McGrath 2008-01-30  526  	} else {
91e7b707 Roland McGrath 2008-01-30  527  		const unsigned long  __user *u = ubuf;
04a1e62c Linus Torvalds 2009-12-17  528  		while (count >= sizeof(*u) && !ret) {
91e7b707 Roland McGrath 2008-01-30  529  			unsigned long word;
91e7b707 Roland McGrath 2008-01-30  530  			ret = __get_user(word, u++);
91e7b707 Roland McGrath 2008-01-30 @531  			if (ret)
91e7b707 Roland McGrath 2008-01-30  532  				break;
91e7b707 Roland McGrath 2008-01-30  533  			ret = putreg(target, pos, word);
91e7b707 Roland McGrath 2008-01-30  534  			count -= sizeof(*u);
91e7b707 Roland McGrath 2008-01-30 @535  			pos += sizeof(*u);
91e7b707 Roland McGrath 2008-01-30  536  		}
91e7b707 Roland McGrath 2008-01-30  537  	}
91e7b707 Roland McGrath 2008-01-30  538  	return ret;

:::::: The code at line 531 was first introduced by commit
:::::: 91e7b707a4776185f91f03bd052aa53af820094e x86: x86 user_regset general regs

:::::: TO: Roland McGrath <roland@redhat.com>
:::::: CC: Ingo Molnar <mingo@elte.hu>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 22734 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user()
  2016-03-09 18:22     ` H. Peter Anvin
@ 2016-03-09 18:27       ` Benjamin LaHaise
  2016-03-09 19:30       ` [PATCH] x86_32: add support for 64 bit __get_user() v2 Benjamin LaHaise
  1 sibling, 0 replies; 14+ messages in thread
From: Benjamin LaHaise @ 2016-03-09 18:27 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Ingo Molnar, Russell King, Thomas Gleixner, x86, linux-kernel

On Wed, Mar 09, 2016 at 10:22:50AM -0800, H. Peter Anvin wrote:
> On 03/09/2016 09:50 AM, Benjamin LaHaise wrote:
> > On Wed, Mar 09, 2016 at 09:36:30AM -0800, H. Peter Anvin wrote:
> >> On March 9, 2016 9:22:25 AM PST, Benjamin LaHaise <bcrl@kvack.org> wrote:
> >>> The existing __get_user() implementation does not support fetching
> >>> 64 bit values on 32 bit x86.  Implement this in a way that does not 
> >>> generate any incorrect warnings as cautioned by Russell King.  Test 
> >>> code available at http://www.kvack.org/~bcrl/x86_32-get_user.tar .  
> > ...
> >> Weird.  I could swear we had already fixed this a few years ago.
> > 
> > That surprised me as well, but Russell raised the fact that the approaches 
> > previously tried on 32 bit architectures had caused various incorrect 
> > compiler warnings for certain obscure cases -- see the code in test_module.c 
> > in that URL that Russell provided to demonstrate the problem across all the 
> > corner cases.
> 
> Oh, I see... I implemented it for put but not get... weird.  You may
> want to look at the __inttype() macro defined earlier in this file; it
> might be useful.

Ah, interesting.  I'll look at that.

> I presume you have already seen:
> 
> >> fs/select.c:710: Error: operand type mismatch for `movq'
> >> fs/select.c:714: Error: incorrect register `%cx' used with `q' suffix
>    fs/select.c:711: Error: operand type mismatch for `movq'
> >> fs/select.c:715: Error: incorrect register `%si' used with `q' suffix
> --
>    fs/aio.c: Assembler messages:
> >> fs/aio.c:1606: Error: operand type mismatch for `movq'
> >> fs/aio.c:1610: Error: incorrect register `%si' used with `q' suffix
> 
> ... which implies it used 16-bit registers for 64-bit operations when
> compiling for 64 bits.

Yup, will respin shortly.

		-ben
-- 
"Thought is the essence of where you are now."

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH] x86_32: add support for 64 bit __get_user() v2
  2016-03-09 18:22     ` H. Peter Anvin
  2016-03-09 18:27       ` Benjamin LaHaise
@ 2016-03-09 19:30       ` Benjamin LaHaise
  2016-03-09 19:41         ` kbuild test robot
                           ` (2 more replies)
  1 sibling, 3 replies; 14+ messages in thread
From: Benjamin LaHaise @ 2016-03-09 19:30 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Ingo Molnar, Russell King, Thomas Gleixner, x86, linux-kernel

The existing __get_user() implementation does not support fetching
64 bit values on 32 bit x86.  Implement this in a way that does not 
generate any incorrect warnings as cautioned by Russell King.  Test 
code available at http://www.kvack.org/~bcrl/x86_32-get_user.tar .

v2: use __inttype() as suggested by H. Peter Anvin, which cleans the
code up nicely, and fix things to work on x86_64 as well.  Tested on 
both 32 bit and 64 bit x86.

Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index a4a30e4..1284da2 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -333,7 +333,25 @@ do {									\
 } while (0)
 
 #ifdef CONFIG_X86_32
-#define __get_user_asm_u64(x, ptr, retval, errret)	(x) = __get_user_bad()
+#define __get_user_asm_u64(x, ptr, retval, errret)			\
+({									\
+	asm volatile(ASM_STAC "\n"					\
+		     "1:	movl %2,%%eax\n"			\
+		     "2:	movl %3,%%edx\n"			\
+		     "3: " ASM_CLAC "\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(1b, 4b)				\
+		     _ASM_EXTABLE(2b, 4b)				\
+		     : "=r" (retval), "=A"(x)				\
+		     : "m" (__m(ptr)), "m" __m(((u32 *)(ptr)) + 1),	\
+		       "i" (errret), "0" (retval));			\
+})
+
 #define __get_user_asm_ex_u64(x, ptr)			(x) = __get_user_bad()
 #else
 #define __get_user_asm_u64(x, ptr, retval, errret) \
@@ -420,7 +438,7 @@ do {									\
 #define __get_user_nocheck(x, ptr, size)				\
 ({									\
 	int __gu_err;							\
-	unsigned long __gu_val;						\
+	__inttype(*(ptr)) __gu_val;					\
 	__uaccess_begin();						\
 	__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);	\
 	__uaccess_end();						\

-- 
"Thought is the essence of where you are now."

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user() v2
  2016-03-09 19:30       ` [PATCH] x86_32: add support for 64 bit __get_user() v2 Benjamin LaHaise
@ 2016-03-09 19:41         ` kbuild test robot
  2016-03-09 20:05         ` [PATCH] x86_32: add support for 64 bit __get_user() v3 Benjamin LaHaise
  2016-03-09 20:24         ` [PATCH] x86_32: add support for 64 bit __get_user() v2 kbuild test robot
  2 siblings, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2016-03-09 19:41 UTC (permalink / raw)
  To: Benjamin LaHaise
  Cc: kbuild-all, H. Peter Anvin, Ingo Molnar, Russell King,
	Thomas Gleixner, x86, linux-kernel

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

Hi Benjamin,

[auto build test WARNING on tip/x86/core]
[also build test WARNING on v4.5-rc7 next-20160309]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Benjamin-LaHaise/x86_32-add-support-for-64-bit-__get_user-v2/20160310-033507
config: i386-tinyconfig (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   In file included from arch/x86/include/asm/sections.h:5:0,
                    from arch/x86/include/asm/hw_irq.h:26,
                    from include/linux/irq.h:418,
                    from arch/x86/include/asm/hardirq.h:5,
                    from include/linux/hardirq.h:8,
                    from include/linux/memcontrol.h:24,
                    from include/linux/tracehook.h:53,
                    from arch/x86/kernel/ptrace.c:14:
   arch/x86/kernel/ptrace.c: In function 'genregs_set':
>> arch/x86/kernel/ptrace.c:530:28: warning: operation on 'u' may be undefined [-Wsequence-point]
       ret = __get_user(word, u++);
                               ^
   arch/x86/include/asm/uaccess.h:451:51: note: in definition of macro '__m'
    #define __m(x) (*(struct __large_struct __user *)(x))
                                                      ^
>> arch/x86/include/asm/uaccess.h:378:3: note: in expansion of macro '__get_user_asm_u64'
      __get_user_asm_u64(x, ptr, retval, errret);  \
      ^
>> arch/x86/include/asm/uaccess.h:443:2: note: in expansion of macro '__get_user_size'
     __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
     ^
>> arch/x86/include/asm/uaccess.h:512:2: note: in expansion of macro '__get_user_nocheck'
     __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     ^
>> arch/x86/kernel/ptrace.c:530:10: note: in expansion of macro '__get_user'
       ret = __get_user(word, u++);
             ^
--
   In file included from lib/bitmap.c:17:0:
   lib/bitmap.c: In function '__bitmap_parse':
>> lib/bitmap.c:377:27: warning: operation on 'ubuf' may be undefined [-Wsequence-point]
        if (__get_user(c, ubuf++))
                              ^
   arch/x86/include/asm/uaccess.h:451:51: note: in definition of macro '__m'
    #define __m(x) (*(struct __large_struct __user *)(x))
                                                      ^
>> arch/x86/include/asm/uaccess.h:378:3: note: in expansion of macro '__get_user_asm_u64'
      __get_user_asm_u64(x, ptr, retval, errret);  \
      ^
>> arch/x86/include/asm/uaccess.h:443:2: note: in expansion of macro '__get_user_size'
     __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
     ^
>> arch/x86/include/asm/uaccess.h:512:2: note: in expansion of macro '__get_user_nocheck'
     __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     ^
>> lib/bitmap.c:377:9: note: in expansion of macro '__get_user'
        if (__get_user(c, ubuf++))
            ^
   lib/bitmap.c: In function '__bitmap_parselist':
   lib/bitmap.c:525:27: warning: operation on 'ubuf' may be undefined [-Wsequence-point]
        if (__get_user(c, ubuf++))
                              ^
   arch/x86/include/asm/uaccess.h:451:51: note: in definition of macro '__m'
    #define __m(x) (*(struct __large_struct __user *)(x))
                                                      ^
>> arch/x86/include/asm/uaccess.h:378:3: note: in expansion of macro '__get_user_asm_u64'
      __get_user_asm_u64(x, ptr, retval, errret);  \
      ^
>> arch/x86/include/asm/uaccess.h:443:2: note: in expansion of macro '__get_user_size'
     __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
     ^
>> arch/x86/include/asm/uaccess.h:512:2: note: in expansion of macro '__get_user_nocheck'
     __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     ^
   lib/bitmap.c:525:9: note: in expansion of macro '__get_user'
        if (__get_user(c, ubuf++))
            ^

vim +/__get_user_asm_u64 +378 arch/x86/include/asm/uaccess.h

3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  372  		__get_user_asm(x, ptr, retval, "w", "w", "=r", errret);	\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  373  		break;							\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  374  	case 4:								\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  375  		__get_user_asm(x, ptr, retval, "l", "k", "=r", errret);	\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  376  		break;							\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  377  	case 8:								\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25 @378  		__get_user_asm_u64(x, ptr, retval, errret);		\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  379  		break;							\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  380  	default:							\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  381  		(x) = __get_user_bad();					\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  382  	}								\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  383  } while (0)
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  384  
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  385  #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  386  	asm volatile("\n"						\
63bcff2a arch/x86/include/asm/uaccess.h H. Peter Anvin    2012-09-21  387  		     "1:	mov"itype" %2,%"rtype"1\n"		\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  388  		     "2:\n"						\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  389  		     ".section .fixup,\"ax\"\n"				\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  390  		     "3:	mov %3,%0\n"				\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  391  		     "	xor"itype" %"rtype"1,%"rtype"1\n"		\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  392  		     "	jmp 2b\n"					\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  393  		     ".previous\n"					\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  394  		     _ASM_EXTABLE(1b, 3b)				\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  395  		     : "=r" (err), ltype(x)				\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  396  		     : "m" (__m(addr)), "i" (errret), "0" (err))
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  397  
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  398  /*
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  399   * This doesn't do __uaccess_begin/end - the exception handling
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  400   * around it must do that.
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  401   */
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  402  #define __get_user_size_ex(x, ptr, size)				\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  403  do {									\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  404  	__chk_user_ptr(ptr);						\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  405  	switch (size) {							\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  406  	case 1:								\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  407  		__get_user_asm_ex(x, ptr, "b", "b", "=q");		\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  408  		break;							\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  409  	case 2:								\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  410  		__get_user_asm_ex(x, ptr, "w", "w", "=r");		\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  411  		break;							\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  412  	case 4:								\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  413  		__get_user_asm_ex(x, ptr, "l", "k", "=r");		\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  414  		break;							\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  415  	case 8:								\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  416  		__get_user_asm_ex_u64(x, ptr);				\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  417  		break;							\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  418  	default:							\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  419  		(x) = __get_user_bad();					\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  420  	}								\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  421  } while (0)
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  422  
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  423  #define __get_user_asm_ex(x, addr, itype, rtype, ltype)			\
5e88353d arch/x86/include/asm/uaccess.h H. Peter Anvin    2012-09-21  424  	asm volatile("1:	mov"itype" %1,%"rtype"0\n"		\
5e88353d arch/x86/include/asm/uaccess.h H. Peter Anvin    2012-09-21  425  		     "2:\n"						\
535c0c34 arch/x86/include/asm/uaccess.h H. Peter Anvin    2012-04-20  426  		     _ASM_EXTABLE_EX(1b, 2b)				\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  427  		     : ltype(x) : "m" (__m(addr)))
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  428  
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  429  #define __put_user_nocheck(x, ptr, size)			\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  430  ({								\
16855f87 arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2008-12-08  431  	int __pu_err;						\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  432  	__uaccess_begin();					\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  433  	__put_user_size((x), (ptr), (size), __pu_err, -EFAULT);	\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  434  	__uaccess_end();					\
a76cf66e arch/x86/include/asm/uaccess.h Andy Lutomirski   2015-10-05  435  	__builtin_expect(__pu_err, 0);				\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  436  })
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  437  
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  438  #define __get_user_nocheck(x, ptr, size)				\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  439  ({									\
16855f87 arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2008-12-08  440  	int __gu_err;							\
7dd119d0 arch/x86/include/asm/uaccess.h Benjamin LaHaise  2016-03-09  441  	__inttype(*(ptr)) __gu_val;					\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  442  	__uaccess_begin();						\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25 @443  	__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);	\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  444  	__uaccess_end();						\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  445  	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
a76cf66e arch/x86/include/asm/uaccess.h Andy Lutomirski   2015-10-05  446  	__builtin_expect(__gu_err, 0);					\
3f168221 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  447  })
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  448  
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  449  /* FIXME: this hack is definitely wrong -AK */
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  450  struct __large_struct { unsigned long buf[100]; };
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25 @451  #define __m(x) (*(struct __large_struct __user *)(x))
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  452  
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  453  /*
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  454   * Tell gcc we read from memory instead of writing: this is because
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  455   * we do not write to any memory gcc knows about, so there are no
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  456   * aliasing issues.
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  457   */
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  458  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  459  	asm volatile("\n"						\
63bcff2a arch/x86/include/asm/uaccess.h H. Peter Anvin    2012-09-21  460  		     "1:	mov"itype" %"rtype"1,%2\n"		\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  461  		     "2:\n"						\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  462  		     ".section .fixup,\"ax\"\n"				\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  463  		     "3:	mov %3,%0\n"				\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  464  		     "	jmp 2b\n"					\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  465  		     ".previous\n"					\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  466  		     _ASM_EXTABLE(1b, 3b)				\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  467  		     : "=r"(err)					\
dc70ddf4 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  468  		     : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  469  
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  470  #define __put_user_asm_ex(x, addr, itype, rtype, ltype)			\
5e88353d arch/x86/include/asm/uaccess.h H. Peter Anvin    2012-09-21  471  	asm volatile("1:	mov"itype" %"rtype"0,%1\n"		\
5e88353d arch/x86/include/asm/uaccess.h H. Peter Anvin    2012-09-21  472  		     "2:\n"						\
535c0c34 arch/x86/include/asm/uaccess.h H. Peter Anvin    2012-04-20  473  		     _ASM_EXTABLE_EX(1b, 2b)				\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  474  		     : : ltype(x), "m" (__m(addr)))
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  475  
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  476  /*
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  477   * uaccess_try and catch
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  478   */
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  479  #define uaccess_try	do {						\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  480  	current_thread_info()->uaccess_err = 0;				\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  481  	__uaccess_begin();						\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  482  	barrier();
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  483  
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  484  #define uaccess_catch(err)						\
11f1a4b9 arch/x86/include/asm/uaccess.h Linus Torvalds    2015-12-17  485  	__uaccess_end();						\
4fc34901 arch/x86/include/asm/uaccess.h Andy Lutomirski   2011-11-07  486  	(err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0);	\
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  487  } while (0)
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  488  
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  489  /**
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  490   * __get_user: - Get a simple variable from user space, with less checking.
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  491   * @x:   Variable to store result.
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  492   * @ptr: Source address, in user space.
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  493   *
b3c395ef arch/x86/include/asm/uaccess.h David Hildenbrand 2015-05-11  494   * Context: User context only. This function may sleep if pagefaults are
b3c395ef arch/x86/include/asm/uaccess.h David Hildenbrand 2015-05-11  495   *          enabled.
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  496   *
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  497   * This macro copies a single simple variable from user space to kernel
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  498   * space.  It supports simple types like char and int, but not larger
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  499   * data types like structures or arrays.
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  500   *
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  501   * @ptr must have pointer-to-simple-variable type, and the result of
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  502   * dereferencing @ptr must be assignable to @x without a cast.
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  503   *
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  504   * Caller must check the pointer with access_ok() before calling this
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  505   * function.
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  506   *
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  507   * Returns zero on success, or -EFAULT on error.
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  508   * On error, the variable @x is set to zero.
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  509   */
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  510  
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  511  #define __get_user(x, ptr)						\
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25 @512  	__get_user_nocheck((x), (ptr), sizeof(*(ptr)))
fe40c0af arch/x86/include/asm/uaccess.h Hiroshi Shimamoto 2009-01-23  513  
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  514  /**
8cb834e9 include/asm-x86/uaccess.h      Glauber Costa     2008-06-25  515   * __put_user: - Write a simple value into user space, with less checking.

:::::: The code at line 378 was first introduced by commit
:::::: 3f168221167ca7a844fde3bf58e1c7ca0bf9741e x86: merge __get_user_asm and its users.

:::::: TO: Glauber Costa <gcosta@redhat.com>
:::::: CC: Ingo Molnar <mingo@elte.hu>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 6205 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH] x86_32: add support for 64 bit __get_user() v3
  2016-03-09 19:30       ` [PATCH] x86_32: add support for 64 bit __get_user() v2 Benjamin LaHaise
  2016-03-09 19:41         ` kbuild test robot
@ 2016-03-09 20:05         ` Benjamin LaHaise
  2016-03-14 15:37           ` Benjamin LaHaise
  2016-03-09 20:24         ` [PATCH] x86_32: add support for 64 bit __get_user() v2 kbuild test robot
  2 siblings, 1 reply; 14+ messages in thread
From: Benjamin LaHaise @ 2016-03-09 20:05 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Ingo Molnar, Russell King, Thomas Gleixner, x86, linux-kernel

The existing __get_user() implementation does not support fetching
64 bit values on 32 bit x86.  Implement this in a way that does not 
generate any incorrect warnings as cautioned by Russell King.  Test 
code available at http://www.kvack.org/~bcrl/x86_32-get_user.tar .

v2: use __inttype() as suggested by H. Peter Anvin, which cleans the
code up nicely, and fix things to work on x86_64 as well.

v3: fix undefined behaviour on 32 bit x86 caused by multiple expansion 
of ptr in the 64 bit case.

Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index a4a30e4..8743552 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -333,7 +333,26 @@ do {									\
 } while (0)
 
 #ifdef CONFIG_X86_32
-#define __get_user_asm_u64(x, ptr, retval, errret)	(x) = __get_user_bad()
+#define __get_user_asm_u64(x, ptr, retval, errret)			\
+({									\
+	__typeof__(ptr) __ptr = (ptr);					\
+	asm volatile(ASM_STAC "\n"					\
+		     "1:	movl %2,%%eax\n"			\
+		     "2:	movl %3,%%edx\n"			\
+		     "3: " ASM_CLAC "\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(1b, 4b)				\
+		     _ASM_EXTABLE(2b, 4b)				\
+		     : "=r" (retval), "=A"(x)				\
+		     : "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1),	\
+		       "i" (errret), "0" (retval));			\
+})
+
 #define __get_user_asm_ex_u64(x, ptr)			(x) = __get_user_bad()
 #else
 #define __get_user_asm_u64(x, ptr, retval, errret) \
@@ -420,7 +439,7 @@ do {									\
 #define __get_user_nocheck(x, ptr, size)				\
 ({									\
 	int __gu_err;							\
-	unsigned long __gu_val;						\
+	__inttype(*(ptr)) __gu_val;					\
 	__uaccess_begin();						\
 	__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);	\
 	__uaccess_end();						\

-- 
"Thought is the essence of where you are now."

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user() v2
  2016-03-09 19:30       ` [PATCH] x86_32: add support for 64 bit __get_user() v2 Benjamin LaHaise
  2016-03-09 19:41         ` kbuild test robot
  2016-03-09 20:05         ` [PATCH] x86_32: add support for 64 bit __get_user() v3 Benjamin LaHaise
@ 2016-03-09 20:24         ` kbuild test robot
  2 siblings, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2016-03-09 20:24 UTC (permalink / raw)
  To: Benjamin LaHaise
  Cc: kbuild-all, H. Peter Anvin, Ingo Molnar, Russell King,
	Thomas Gleixner, x86, linux-kernel

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

Hi Benjamin,

[auto build test WARNING on tip/x86/core]
[also build test WARNING on v4.5-rc7 next-20160309]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Benjamin-LaHaise/x86_32-add-support-for-64-bit-__get_user-v2/20160310-033507
config: i386-randconfig-s1-201610 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   In file included from include/uapi/linux/stddef.h:1:0,
                    from include/linux/stddef.h:4,
                    from include/uapi/linux/posix_types.h:4,
                    from include/uapi/linux/types.h:13,
                    from include/linux/types.h:5,
                    from include/linux/thread_info.h:10,
                    from lib/bitmap.c:9:
   lib/bitmap.c: In function '__bitmap_parse':
   lib/bitmap.c:377:27: warning: operation on 'ubuf' may be undefined [-Wsequence-point]
        if (__get_user(c, ubuf++))
                              ^
   include/linux/compiler.h:147:28: note: in definition of macro '__trace_if'
     if (__builtin_constant_p((cond)) ? !!(cond) :   \
                               ^
>> lib/bitmap.c:377:5: note: in expansion of macro 'if'
        if (__get_user(c, ubuf++))
        ^
>> arch/x86/include/asm/uaccess.h:351:15: note: in expansion of macro '__m'
           : "m" (__m(ptr)), "m" __m(((u32 *)(ptr)) + 1), \
                  ^
   arch/x86/include/asm/uaccess.h:378:3: note: in expansion of macro '__get_user_asm_u64'
      __get_user_asm_u64(x, ptr, retval, errret);  \
      ^
   arch/x86/include/asm/uaccess.h:443:2: note: in expansion of macro '__get_user_size'
     __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
     ^
   arch/x86/include/asm/uaccess.h:512:2: note: in expansion of macro '__get_user_nocheck'
     __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     ^
   lib/bitmap.c:377:9: note: in expansion of macro '__get_user'
        if (__get_user(c, ubuf++))
            ^
   lib/bitmap.c:377:27: warning: operation on 'ubuf' may be undefined [-Wsequence-point]
        if (__get_user(c, ubuf++))
                              ^
   include/linux/compiler.h:147:40: note: in definition of macro '__trace_if'
     if (__builtin_constant_p((cond)) ? !!(cond) :   \
                                           ^
>> lib/bitmap.c:377:5: note: in expansion of macro 'if'
        if (__get_user(c, ubuf++))
        ^
>> arch/x86/include/asm/uaccess.h:351:15: note: in expansion of macro '__m'
           : "m" (__m(ptr)), "m" __m(((u32 *)(ptr)) + 1), \
                  ^
   arch/x86/include/asm/uaccess.h:378:3: note: in expansion of macro '__get_user_asm_u64'
      __get_user_asm_u64(x, ptr, retval, errret);  \
      ^
   arch/x86/include/asm/uaccess.h:443:2: note: in expansion of macro '__get_user_size'
     __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
     ^
   arch/x86/include/asm/uaccess.h:512:2: note: in expansion of macro '__get_user_nocheck'
     __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     ^
   lib/bitmap.c:377:9: note: in expansion of macro '__get_user'
        if (__get_user(c, ubuf++))
            ^
   lib/bitmap.c:377:27: warning: operation on 'ubuf' may be undefined [-Wsequence-point]
        if (__get_user(c, ubuf++))
                              ^
   include/linux/compiler.h:158:16: note: in definition of macro '__trace_if'
      ______r = !!(cond);     \
                   ^
>> lib/bitmap.c:377:5: note: in expansion of macro 'if'
        if (__get_user(c, ubuf++))
        ^
>> arch/x86/include/asm/uaccess.h:351:15: note: in expansion of macro '__m'
           : "m" (__m(ptr)), "m" __m(((u32 *)(ptr)) + 1), \
                  ^
   arch/x86/include/asm/uaccess.h:378:3: note: in expansion of macro '__get_user_asm_u64'
      __get_user_asm_u64(x, ptr, retval, errret);  \
      ^
   arch/x86/include/asm/uaccess.h:443:2: note: in expansion of macro '__get_user_size'
     __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
     ^
   arch/x86/include/asm/uaccess.h:512:2: note: in expansion of macro '__get_user_nocheck'
     __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     ^
   lib/bitmap.c:377:9: note: in expansion of macro '__get_user'
        if (__get_user(c, ubuf++))
            ^
   lib/bitmap.c: In function '__bitmap_parselist':
   lib/bitmap.c:525:27: warning: operation on 'ubuf' may be undefined [-Wsequence-point]
        if (__get_user(c, ubuf++))
                              ^
   include/linux/compiler.h:147:28: note: in definition of macro '__trace_if'
     if (__builtin_constant_p((cond)) ? !!(cond) :   \
                               ^
   lib/bitmap.c:525:5: note: in expansion of macro 'if'
        if (__get_user(c, ubuf++))
        ^
>> arch/x86/include/asm/uaccess.h:351:15: note: in expansion of macro '__m'
           : "m" (__m(ptr)), "m" __m(((u32 *)(ptr)) + 1), \
                  ^
   arch/x86/include/asm/uaccess.h:378:3: note: in expansion of macro '__get_user_asm_u64'
      __get_user_asm_u64(x, ptr, retval, errret);  \
      ^
   arch/x86/include/asm/uaccess.h:443:2: note: in expansion of macro '__get_user_size'
     __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
     ^
   arch/x86/include/asm/uaccess.h:512:2: note: in expansion of macro '__get_user_nocheck'
     __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     ^
   lib/bitmap.c:525:9: note: in expansion of macro '__get_user'
        if (__get_user(c, ubuf++))
            ^
   lib/bitmap.c:525:27: warning: operation on 'ubuf' may be undefined [-Wsequence-point]
        if (__get_user(c, ubuf++))
                              ^
   include/linux/compiler.h:147:40: note: in definition of macro '__trace_if'
     if (__builtin_constant_p((cond)) ? !!(cond) :   \
                                           ^
   lib/bitmap.c:525:5: note: in expansion of macro 'if'
        if (__get_user(c, ubuf++))
        ^
>> arch/x86/include/asm/uaccess.h:351:15: note: in expansion of macro '__m'
           : "m" (__m(ptr)), "m" __m(((u32 *)(ptr)) + 1), \
                  ^
   arch/x86/include/asm/uaccess.h:378:3: note: in expansion of macro '__get_user_asm_u64'
      __get_user_asm_u64(x, ptr, retval, errret);  \
      ^
   arch/x86/include/asm/uaccess.h:443:2: note: in expansion of macro '__get_user_size'
     __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
     ^
   arch/x86/include/asm/uaccess.h:512:2: note: in expansion of macro '__get_user_nocheck'
     __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     ^
   lib/bitmap.c:525:9: note: in expansion of macro '__get_user'
        if (__get_user(c, ubuf++))
            ^
   lib/bitmap.c:525:27: warning: operation on 'ubuf' may be undefined [-Wsequence-point]
        if (__get_user(c, ubuf++))
                              ^
   include/linux/compiler.h:158:16: note: in definition of macro '__trace_if'
      ______r = !!(cond);     \
                   ^
   lib/bitmap.c:525:5: note: in expansion of macro 'if'
        if (__get_user(c, ubuf++))
        ^
>> arch/x86/include/asm/uaccess.h:351:15: note: in expansion of macro '__m'
           : "m" (__m(ptr)), "m" __m(((u32 *)(ptr)) + 1), \
                  ^
   arch/x86/include/asm/uaccess.h:378:3: note: in expansion of macro '__get_user_asm_u64'
      __get_user_asm_u64(x, ptr, retval, errret);  \
      ^
   arch/x86/include/asm/uaccess.h:443:2: note: in expansion of macro '__get_user_size'
     __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
     ^
   arch/x86/include/asm/uaccess.h:512:2: note: in expansion of macro '__get_user_nocheck'
     __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     ^
   lib/bitmap.c:525:9: note: in expansion of macro '__get_user'
        if (__get_user(c, ubuf++))
            ^

vim +/__m +351 arch/x86/include/asm/uaccess.h

   335	#ifdef CONFIG_X86_32
   336	#define __get_user_asm_u64(x, ptr, retval, errret)			\
   337	({									\
   338		asm volatile(ASM_STAC "\n"					\
   339			     "1:	movl %2,%%eax\n"			\
   340			     "2:	movl %3,%%edx\n"			\
   341			     "3: " ASM_CLAC "\n"				\
   342			     ".section .fixup,\"ax\"\n"				\
   343			     "4:	mov %4,%0\n"				\
   344			     "	xorl %%eax,%%eax\n"				\
   345			     "	xorl %%edx,%%edx\n"				\
   346			     "	jmp 3b\n"					\
   347			     ".previous\n"					\
   348			     _ASM_EXTABLE(1b, 4b)				\
   349			     _ASM_EXTABLE(2b, 4b)				\
   350			     : "=r" (retval), "=A"(x)				\
 > 351			     : "m" (__m(ptr)), "m" __m(((u32 *)(ptr)) + 1),	\
   352			       "i" (errret), "0" (retval));			\
   353	})
   354	
   355	#define __get_user_asm_ex_u64(x, ptr)			(x) = __get_user_bad()
   356	#else
   357	#define __get_user_asm_u64(x, ptr, retval, errret) \
   358		 __get_user_asm(x, ptr, retval, "q", "", "=r", errret)
   359	#define __get_user_asm_ex_u64(x, ptr) \

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 21582 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user() v3
  2016-03-09 20:05         ` [PATCH] x86_32: add support for 64 bit __get_user() v3 Benjamin LaHaise
@ 2016-03-14 15:37           ` Benjamin LaHaise
  2016-03-14 16:39             ` Ingo Molnar
  0 siblings, 1 reply; 14+ messages in thread
From: Benjamin LaHaise @ 2016-03-14 15:37 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Ingo Molnar, Russell King, Thomas Gleixner, x86, linux-kernel

Any more comments/feedback on this?  Can this be merged for 4.6?

		-ben

On Wed, Mar 09, 2016 at 03:05:56PM -0500, Benjamin LaHaise wrote:
> The existing __get_user() implementation does not support fetching
> 64 bit values on 32 bit x86.  Implement this in a way that does not 
> generate any incorrect warnings as cautioned by Russell King.  Test 
> code available at http://www.kvack.org/~bcrl/x86_32-get_user.tar .
> 
> v2: use __inttype() as suggested by H. Peter Anvin, which cleans the
> code up nicely, and fix things to work on x86_64 as well.
> 
> v3: fix undefined behaviour on 32 bit x86 caused by multiple expansion 
> of ptr in the 64 bit case.
> 
> Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
> 
> diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
> index a4a30e4..8743552 100644
> --- a/arch/x86/include/asm/uaccess.h
> +++ b/arch/x86/include/asm/uaccess.h
> @@ -333,7 +333,26 @@ do {									\
>  } while (0)
>  
>  #ifdef CONFIG_X86_32
> -#define __get_user_asm_u64(x, ptr, retval, errret)	(x) = __get_user_bad()
> +#define __get_user_asm_u64(x, ptr, retval, errret)			\
> +({									\
> +	__typeof__(ptr) __ptr = (ptr);					\
> +	asm volatile(ASM_STAC "\n"					\
> +		     "1:	movl %2,%%eax\n"			\
> +		     "2:	movl %3,%%edx\n"			\
> +		     "3: " ASM_CLAC "\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(1b, 4b)				\
> +		     _ASM_EXTABLE(2b, 4b)				\
> +		     : "=r" (retval), "=A"(x)				\
> +		     : "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1),	\
> +		       "i" (errret), "0" (retval));			\
> +})
> +
>  #define __get_user_asm_ex_u64(x, ptr)			(x) = __get_user_bad()
>  #else
>  #define __get_user_asm_u64(x, ptr, retval, errret) \
> @@ -420,7 +439,7 @@ do {									\
>  #define __get_user_nocheck(x, ptr, size)				\
>  ({									\
>  	int __gu_err;							\
> -	unsigned long __gu_val;						\
> +	__inttype(*(ptr)) __gu_val;					\
>  	__uaccess_begin();						\
>  	__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);	\
>  	__uaccess_end();						\
> 
> -- 
> "Thought is the essence of where you are now."

-- 
"Thought is the essence of where you are now."

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] x86_32: add support for 64 bit __get_user() v3
  2016-03-14 15:37           ` Benjamin LaHaise
@ 2016-03-14 16:39             ` Ingo Molnar
  0 siblings, 0 replies; 14+ messages in thread
From: Ingo Molnar @ 2016-03-14 16:39 UTC (permalink / raw)
  To: Benjamin LaHaise
  Cc: H. Peter Anvin, Ingo Molnar, Russell King, Thomas Gleixner, x86,
	linux-kernel


* Benjamin LaHaise <bcrl@kvack.org> wrote:

> Any more comments/feedback on this?  Can this be merged for 4.6?

Will get to it once the merge window calms down.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-03-14 16:39 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-09 17:22 [PATCH] x86_32: add support for 64 bit __get_user() Benjamin LaHaise
2016-03-09 17:36 ` H. Peter Anvin
2016-03-09 17:50   ` Benjamin LaHaise
2016-03-09 18:22     ` H. Peter Anvin
2016-03-09 18:27       ` Benjamin LaHaise
2016-03-09 19:30       ` [PATCH] x86_32: add support for 64 bit __get_user() v2 Benjamin LaHaise
2016-03-09 19:41         ` kbuild test robot
2016-03-09 20:05         ` [PATCH] x86_32: add support for 64 bit __get_user() v3 Benjamin LaHaise
2016-03-14 15:37           ` Benjamin LaHaise
2016-03-14 16:39             ` Ingo Molnar
2016-03-09 20:24         ` [PATCH] x86_32: add support for 64 bit __get_user() v2 kbuild test robot
2016-03-09 18:17 ` [PATCH] x86_32: add support for 64 bit __get_user() kbuild test robot
2016-03-09 18:22 ` kbuild test robot
2016-03-09 18:23 ` kbuild test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).