Message ID | 20210722124814.778059-5-arnd@kernel.org (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | asm-generic: strncpy_from_user/strnlen_user cleanup | expand |
On Thu, Jul 22, 2021 at 02:48:09PM +0200, Arnd Bergmann wrote: > From: Arnd Bergmann <arnd@arndb.de> > > 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. > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> Looks good, Reviewed-by: Christoph Hellwig <hch@lst.de>
On 7/22/21 5:48 AM, Arnd Bergmann wrote: > From: Arnd Bergmann <arnd@arndb.de> > > 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. > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> LGTM. Thx for doing this Arnd ! Acked-by: Vineet Gupta <vgupta@synopsys.com> -Vineet > --- > arch/arc/Kconfig | 2 + > arch/arc/include/asm/uaccess.h | 83 ++-------------------------------- > arch/arc/mm/extable.c | 12 ----- > 3 files changed, 7 insertions(+), 90 deletions(-) > > diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig > index d8f51eb8963b..64e5f9366401 100644 > --- a/arch/arc/Kconfig > +++ b/arch/arc/Kconfig > @@ -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 > diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h > index 3476348f361e..754a23f26736 100644 > --- a/arch/arc/include/asm/uaccess.h > +++ b/arch/arc/include/asm/uaccess.h > @@ -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> > > diff --git a/arch/arc/mm/extable.c b/arch/arc/mm/extable.c > index b06b09ddf924..4e14c4244ea2 100644 > --- a/arch/arc/mm/extable.c > +++ b/arch/arc/mm/extable.c > @@ -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
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index d8f51eb8963b..64e5f9366401 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -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 diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h index 3476348f361e..754a23f26736 100644 --- a/arch/arc/include/asm/uaccess.h +++ b/arch/arc/include/asm/uaccess.h @@ -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> diff --git a/arch/arc/mm/extable.c b/arch/arc/mm/extable.c index b06b09ddf924..4e14c4244ea2 100644 --- a/arch/arc/mm/extable.c +++ b/arch/arc/mm/extable.c @@ -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