arc: use generic strncpy/strnlen from_user
authorArnd Bergmann <arnd@arndb.de>
Thu, 16 Jan 2020 14:58:41 +0000 (15:58 +0100)
committerArnd Bergmann <arnd@arndb.de>
Fri, 23 Jul 2021 12:40:01 +0000 (14:40 +0200)
Remove the arc implemenation of strncpy/strnlen and instead use the
generic versions.  The arc version is fairly slow because it always does
byte accesses even for aligned data, and its checks for user_addr_max()
differ from the generic code.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
arch/arc/Kconfig
arch/arc/include/asm/uaccess.h
arch/arc/mm/extable.c

index d8f51eb..64e5f93 100644 (file)
@@ -27,6 +27,8 @@ config ARC
        select GENERIC_PENDING_IRQ if SMP
        select GENERIC_SCHED_CLOCK
        select GENERIC_SMP_IDLE_THREAD
+       select GENERIC_STRNCPY_FROM_USER
+       select GENERIC_STRNLEN_USER
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE if ARC_MMU_V4
index 3476348..754a23f 100644 (file)
@@ -655,96 +655,23 @@ static inline unsigned long __arc_clear_user(void __user *to, unsigned long n)
        return res;
 }
 
-static inline long
-__arc_strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       long res = 0;
-       char val;
-
-       if (!access_ok(src, 1))
-               return -EFAULT;
-
-       if (count == 0)
-               return 0;
-
-       __asm__ __volatile__(
-       "       mov     lp_count, %5            \n"
-       "       lp      3f                      \n"
-       "1:     ldb.ab  %3, [%2, 1]             \n"
-       "       breq.d  %3, 0, 3f               \n"
-       "       stb.ab  %3, [%1, 1]             \n"
-       "       add     %0, %0, 1       # Num of NON NULL bytes copied  \n"
-       "3:                                                             \n"
-       "       .section .fixup, \"ax\"         \n"
-       "       .align 4                        \n"
-       "4:     mov %0, %4              # sets @res as -EFAULT  \n"
-       "       j   3b                          \n"
-       "       .previous                       \n"
-       "       .section __ex_table, \"a\"      \n"
-       "       .align 4                        \n"
-       "       .word   1b, 4b                  \n"
-       "       .previous                       \n"
-       : "+r"(res), "+r"(dst), "+r"(src), "=r"(val)
-       : "g"(-EFAULT), "r"(count)
-       : "lp_count", "memory");
-
-       return res;
-}
-
-static inline long __arc_strnlen_user(const char __user *s, long n)
-{
-       long res, tmp1, cnt;
-       char val;
-
-       if (!access_ok(s, 1))
-               return 0;
-
-       __asm__ __volatile__(
-       "       mov %2, %1                      \n"
-       "1:     ldb.ab  %3, [%0, 1]             \n"
-       "       breq.d  %3, 0, 2f               \n"
-       "       sub.f   %2, %2, 1               \n"
-       "       bnz 1b                          \n"
-       "       sub %2, %2, 1                   \n"
-       "2:     sub %0, %1, %2                  \n"
-       "3:     ;nop                            \n"
-       "       .section .fixup, \"ax\"         \n"
-       "       .align 4                        \n"
-       "4:     mov %0, 0                       \n"
-       "       j   3b                          \n"
-       "       .previous                       \n"
-       "       .section __ex_table, \"a\"      \n"
-       "       .align 4                        \n"
-       "       .word 1b, 4b                    \n"
-       "       .previous                       \n"
-       : "=r"(res), "=r"(tmp1), "=r"(cnt), "=r"(val)
-       : "0"(s), "1"(n)
-       : "memory");
-
-       return res;
-}
-
 #ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE
 
 #define INLINE_COPY_TO_USER
 #define INLINE_COPY_FROM_USER
 
 #define __clear_user(d, n)             __arc_clear_user(d, n)
-#define strncpy_from_user(d, s, n)     __arc_strncpy_from_user(d, s, n)
-#define strnlen_user(s, n)             __arc_strnlen_user(s, n)
 #else
 extern unsigned long arc_clear_user_noinline(void __user *to,
                unsigned long n);
-extern long arc_strncpy_from_user_noinline (char *dst, const char __user *src,
-               long count);
-extern long arc_strnlen_user_noinline(const char __user *src, long n);
-
 #define __clear_user(d, n)             arc_clear_user_noinline(d, n)
-#define strncpy_from_user(d, s, n)     arc_strncpy_from_user_noinline(d, s, n)
-#define strnlen_user(s, n)             arc_strnlen_user_noinline(s, n)
-
 #endif
 
+extern long strncpy_from_user(char *dst, const char __user *src, long count);
+#define strncpy_from_user(d, s, n)     strncpy_from_user(d, s, n)
+extern long strnlen_user(const char __user *src, long n);
+#define strnlen_user(s, n)             strnlen_user(s, n)
+
 #include <asm/segment.h>
 #include <asm-generic/uaccess.h>
 
index b06b09d..4e14c42 100644 (file)
@@ -32,16 +32,4 @@ unsigned long arc_clear_user_noinline(void __user *to,
 }
 EXPORT_SYMBOL(arc_clear_user_noinline);
 
-long arc_strncpy_from_user_noinline(char *dst, const char __user *src,
-               long count)
-{
-       return __arc_strncpy_from_user(dst, src, count);
-}
-EXPORT_SYMBOL(arc_strncpy_from_user_noinline);
-
-long arc_strnlen_user_noinline(const char __user *src, long n)
-{
-       return __arc_strnlen_user(src, n);
-}
-EXPORT_SYMBOL(arc_strnlen_user_noinline);
 #endif