parisc: Add 64bit get_user() and put_user() for 32bit kernel
authorHelge Deller <deller@gmx.de>
Sat, 9 Apr 2016 06:27:08 +0000 (08:27 +0200)
committerHelge Deller <deller@gmx.de>
Sun, 22 May 2016 19:39:04 +0000 (21:39 +0200)
Allow accessing 64-bit values in userspace from a 32-bit kernel.
The access is not atomic.

Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/include/asm/uaccess.h

index 56b7208da9a43f863aa78dfb81cd8daa455501dc..0f59fd9ca20526d8a27066c724ab2499965ec62c 100644 (file)
@@ -40,7 +40,7 @@ static inline long access_ok(int type, const void __user * addr,
 #define get_user __get_user
 
 #if !defined(CONFIG_64BIT)
-#define LDD_USER(ptr)          BUILD_BUG()
+#define LDD_USER(ptr)          __get_user_asm64(ptr)
 #define STD_USER(x, ptr)       __put_user_asm64(x, ptr)
 #else
 #define LDD_USER(ptr)          __get_user_asm("ldd", ptr)
@@ -114,6 +114,20 @@ struct exception_data {
                : "r"(ptr), "1"(__gu_err)               \
                : "r1");
 
+#if !defined(CONFIG_64BIT)
+
+#define __get_user_asm64(ptr)                          \
+       __asm__("\n1:\tldw 0(%%sr2,%2),%0"              \
+               "\n2:\tldw 4(%%sr2,%2),%R0\n\t"         \
+               ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_2)\
+               ASM_EXCEPTIONTABLE_ENTRY(2b, fixup_get_user_skip_1)\
+               : "=r"(__gu_val), "=r"(__gu_err)        \
+               : "r"(ptr), "1"(__gu_err)               \
+               : "r1");
+
+#endif /* !defined(CONFIG_64BIT) */
+
+
 #define __put_user(x, ptr)                                      \
 ({                                                             \
        register long __pu_err __asm__ ("r8") = 0;              \