diff mbox

linux-next: build failure after merge of the aio tree

Message ID 20160204160101.GD16315@kvack.org (mailing list archive)
State New, archived
Headers show

Commit Message

Benjamin LaHaise Feb. 4, 2016, 4:01 p.m. UTC
On Thu, Feb 04, 2016 at 02:39:07PM +0000, Russell King - ARM Linux wrote:
> However, this one should warn:
> 
> int test_wrong(char **v, const char **p)
> { return __get_user(*v, p); }
> 
> Good luck (I think you'll need lots of it to get a working solution)! :)

This works with your test cases on x86-32.  Note that it's only compile + 
link tested at present.

		-ben

Comments

Russell King - ARM Linux Feb. 4, 2016, 4:17 p.m. UTC | #1
On Thu, Feb 04, 2016 at 11:01:01AM -0500, Benjamin LaHaise wrote:
> On Thu, Feb 04, 2016 at 02:39:07PM +0000, Russell King - ARM Linux wrote:
> > However, this one should warn:
> > 
> > int test_wrong(char **v, const char **p)
> > { return __get_user(*v, p); }
> > 
> > Good luck (I think you'll need lots of it to get a working solution)! :)
> 
> This works with your test cases on x86-32.  Note that it's only compile + 
> link tested at present.

That's the easy bit!

The problem you're going to run into is here:

#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;                     \

__gu_val will be 32-bit, even when you're wanting a 64-bit quantity.
That's where the fun and games start...
Benjamin LaHaise Feb. 4, 2016, 4:27 p.m. UTC | #2
On Thu, Feb 04, 2016 at 04:17:42PM +0000, Russell King - ARM Linux wrote:
> On Thu, Feb 04, 2016 at 11:01:01AM -0500, Benjamin LaHaise wrote:
> > On Thu, Feb 04, 2016 at 02:39:07PM +0000, Russell King - ARM Linux wrote:
> > > However, this one should warn:
> > > 
> > > int test_wrong(char **v, const char **p)
> > > { return __get_user(*v, p); }
> > > 
> > > Good luck (I think you'll need lots of it to get a working solution)! :)
> > 
> > This works with your test cases on x86-32.  Note that it's only compile + 
> > link tested at present.
> 
> That's the easy bit!
> 
> The problem you're going to run into is here:
> 
> #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;                     \
> 
> __gu_val will be 32-bit, even when you're wanting a 64-bit quantity.
> That's where the fun and games start...

Ugh.  You're making me install a 32 bit distro.....!

		-ben

> -- 
> RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.
Benjamin LaHaise Feb. 4, 2016, 4:47 p.m. UTC | #3
On Thu, Feb 04, 2016 at 04:17:42PM +0000, Russell King - ARM Linux wrote:
> That's the easy bit!
> 
> The problem you're going to run into is here:
> 
> #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;                     \
> 
> __gu_val will be 32-bit, even when you're wanting a 64-bit quantity.
> That's where the fun and games start...

You're right -- it's quite non-trivial.  How evil would it be to make a 
separate __get_user64() macro?

		-ben
diff mbox

Patch

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 09b1b0a..d8834c2 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -326,7 +326,21 @@  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"			\
+		     "		movl %3,%%edx\n"			\
+		     "2: " ASM_CLAC "\n"				\
+		     ".section .fixup,\"ax\"\n"				\
+		     "3:	mov %4,%0\n"				\
+		     "	xorl %%eax,%%eax\n"				\
+		     "	xorl %%edx,%%edx\n"				\
+		     "	jmp 2b\n"					\
+		     ".previous\n"					\
+		     _ASM_EXTABLE(1b, 3b)				\
+		     : "=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) \