riscv: refactor __get_user and __put_user
authorChristoph Hellwig <hch@lst.de>
Mon, 7 Sep 2020 05:58:23 +0000 (07:58 +0200)
committerPalmer Dabbelt <palmerdabbelt@google.com>
Sun, 4 Oct 2020 17:27:08 +0000 (10:27 -0700)
Add new __get_user_nocheck and __put_user_nocheck that switch on the size
and call the actual inline assembly helpers, and move the uaccess enable
/ disable into the actual __get_user and __put_user.  This prepares for
natively implementing __get_kernel_nofault and __put_kernel_nofault.

Also don't bother with the deprecated register keyword for the error
return.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
arch/riscv/include/asm/uaccess.h

index e8eedf2..b67d1c6 100644 (file)
@@ -107,7 +107,6 @@ static inline int __access_ok(unsigned long addr, unsigned long size)
 do {                                                           \
        uintptr_t __tmp;                                        \
        __typeof__(x) __x;                                      \
-       __enable_user_access();                                 \
        __asm__ __volatile__ (                                  \
                "1:\n"                                          \
                "       " insn " %1, %3\n"                      \
@@ -125,7 +124,6 @@ do {                                                                \
                "       .previous"                              \
                : "+r" (err), "=&r" (__x), "=r" (__tmp)         \
                : "m" (*(ptr)), "i" (-EFAULT));                 \
-       __disable_user_access();                                \
        (x) = __x;                                              \
 } while (0)
 
@@ -138,7 +136,6 @@ do {                                                                \
        u32 __user *__ptr = (u32 __user *)(ptr);                \
        u32 __lo, __hi;                                         \
        uintptr_t __tmp;                                        \
-       __enable_user_access();                                 \
        __asm__ __volatile__ (                                  \
                "1:\n"                                          \
                "       lw %1, %4\n"                            \
@@ -162,12 +159,30 @@ do {                                                              \
                        "=r" (__tmp)                            \
                : "m" (__ptr[__LSW]), "m" (__ptr[__MSW]),       \
                        "i" (-EFAULT));                         \
-       __disable_user_access();                                \
        (x) = (__typeof__(x))((__typeof__((x)-(x)))(            \
                (((u64)__hi << 32) | __lo)));                   \
 } while (0)
 #endif /* CONFIG_64BIT */
 
+#define __get_user_nocheck(x, __gu_ptr, __gu_err)              \
+do {                                                           \
+       switch (sizeof(*__gu_ptr)) {                            \
+       case 1:                                                 \
+               __get_user_asm("lb", (x), __gu_ptr, __gu_err);  \
+               break;                                          \
+       case 2:                                                 \
+               __get_user_asm("lh", (x), __gu_ptr, __gu_err);  \
+               break;                                          \
+       case 4:                                                 \
+               __get_user_asm("lw", (x), __gu_ptr, __gu_err);  \
+               break;                                          \
+       case 8:                                                 \
+               __get_user_8((x), __gu_ptr, __gu_err);  \
+               break;                                          \
+       default:                                                \
+               BUILD_BUG();                                    \
+       }                                                       \
+} while (0)
 
 /**
  * __get_user: - Get a simple variable from user space, with less checking.
@@ -191,25 +206,15 @@ do {                                                              \
  */
 #define __get_user(x, ptr)                                     \
 ({                                                             \
-       register long __gu_err = 0;                             \
        const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);      \
+       long __gu_err = 0;                                      \
+                                                               \
        __chk_user_ptr(__gu_ptr);                               \
-       switch (sizeof(*__gu_ptr)) {                            \
-       case 1:                                                 \
-               __get_user_asm("lb", (x), __gu_ptr, __gu_err);  \
-               break;                                          \
-       case 2:                                                 \
-               __get_user_asm("lh", (x), __gu_ptr, __gu_err);  \
-               break;                                          \
-       case 4:                                                 \
-               __get_user_asm("lw", (x), __gu_ptr, __gu_err);  \
-               break;                                          \
-       case 8:                                                 \
-               __get_user_8((x), __gu_ptr, __gu_err);  \
-               break;                                          \
-       default:                                                \
-               BUILD_BUG();                                    \
-       }                                                       \
+                                                               \
+       __enable_user_access();                                 \
+       __get_user_nocheck(x, __gu_ptr, __gu_err);              \
+       __disable_user_access();                                \
+                                                               \
        __gu_err;                                               \
 })
 
@@ -243,7 +248,6 @@ do {                                                                \
 do {                                                           \
        uintptr_t __tmp;                                        \
        __typeof__(*(ptr)) __x = x;                             \
-       __enable_user_access();                                 \
        __asm__ __volatile__ (                                  \
                "1:\n"                                          \
                "       " insn " %z3, %2\n"                     \
@@ -260,7 +264,6 @@ do {                                                                \
                "       .previous"                              \
                : "+r" (err), "=r" (__tmp), "=m" (*(ptr))       \
                : "rJ" (__x), "i" (-EFAULT));                   \
-       __disable_user_access();                                \
 } while (0)
 
 #ifdef CONFIG_64BIT
@@ -272,7 +275,6 @@ do {                                                                \
        u32 __user *__ptr = (u32 __user *)(ptr);                \
        u64 __x = (__typeof__((x)-(x)))(x);                     \
        uintptr_t __tmp;                                        \
-       __enable_user_access();                                 \
        __asm__ __volatile__ (                                  \
                "1:\n"                                          \
                "       sw %z4, %2\n"                           \
@@ -294,10 +296,28 @@ do {                                                              \
                        "=m" (__ptr[__LSW]),                    \
                        "=m" (__ptr[__MSW])                     \
                : "rJ" (__x), "rJ" (__x >> 32), "i" (-EFAULT)); \
-       __disable_user_access();                                \
 } while (0)
 #endif /* CONFIG_64BIT */
 
+#define __put_user_nocheck(x, __gu_ptr, __pu_err)                                      \
+do {                                                           \
+       switch (sizeof(*__gu_ptr)) {                            \
+       case 1:                                                 \
+               __put_user_asm("sb", (x), __gu_ptr, __pu_err);  \
+               break;                                          \
+       case 2:                                                 \
+               __put_user_asm("sh", (x), __gu_ptr, __pu_err);  \
+               break;                                          \
+       case 4:                                                 \
+               __put_user_asm("sw", (x), __gu_ptr, __pu_err);  \
+               break;                                          \
+       case 8:                                                 \
+               __put_user_8((x), __gu_ptr, __pu_err);  \
+               break;                                          \
+       default:                                                \
+               BUILD_BUG();                                    \
+       }                                                       \
+} while (0)
 
 /**
  * __put_user: - Write a simple value into user space, with less checking.
@@ -320,25 +340,15 @@ do {                                                              \
  */
 #define __put_user(x, ptr)                                     \
 ({                                                             \
-       register long __pu_err = 0;                             \
        __typeof__(*(ptr)) __user *__gu_ptr = (ptr);            \
+       long __pu_err = 0;                                      \
+                                                               \
        __chk_user_ptr(__gu_ptr);                               \
-       switch (sizeof(*__gu_ptr)) {                            \
-       case 1:                                                 \
-               __put_user_asm("sb", (x), __gu_ptr, __pu_err);  \
-               break;                                          \
-       case 2:                                                 \
-               __put_user_asm("sh", (x), __gu_ptr, __pu_err);  \
-               break;                                          \
-       case 4:                                                 \
-               __put_user_asm("sw", (x), __gu_ptr, __pu_err);  \
-               break;                                          \
-       case 8:                                                 \
-               __put_user_8((x), __gu_ptr, __pu_err);  \
-               break;                                          \
-       default:                                                \
-               BUILD_BUG();                                    \
-       }                                                       \
+                                                               \
+       __enable_user_access();                                 \
+       __put_user_nocheck(x, __gu_ptr, __pu_err);              \
+       __disable_user_access();                                \
+                                                               \
        __pu_err;                                               \
 })