[PATCH v3 4/9] arc: use generic strncpy/strnlen from_user

Vineet Gupta Vineet.Gupta1 at synopsys.com
Thu Jul 22 08:34:31 PDT 2021


On 7/22/21 5:48 AM, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at 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 at arndb.de>

LGTM. Thx for doing this Arnd !

Acked-by: Vineet Gupta <vgupta at 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



More information about the linux-um mailing list