Commit b26b1816 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

microblaze: use generic strncpy/strnlen from_user



Remove the microblaze implemenation of strncpy/strnlen and instead use
the generic versions.  The microblaze version is fairly slow because it
always does byte accesses even for aligned data, and it lacks a checks
for user_addr_max().

Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 0cd11518
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ config MICROBLAZE
	select GENERIC_IRQ_SHOW
	select GENERIC_PCI_IOMAP
	select GENERIC_SCHED_CLOCK
	select GENERIC_STRNCPY_FROM_USER
	select GENERIC_STRNLEN_USER
	select HAVE_ARCH_HASH
	select HAVE_ARCH_KGDB
	select HAVE_ARCH_SECCOMP
+4 −17
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@

# define get_fs()	(current_thread_info()->addr_limit)
# define set_fs(val)	(current_thread_info()->addr_limit = (val))
# define user_addr_max() get_fs().seg

# define uaccess_kernel()	(get_fs().seg == KERNEL_DS.seg)

@@ -296,28 +297,14 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
/*
 * Copy a null terminated string from userspace.
 */
extern int __strncpy_user(char *to, const char __user *from, int len);

static inline long
strncpy_from_user(char *dst, const char __user *src, long count)
{
	if (!access_ok(src, 1))
		return -EFAULT;
	return __strncpy_user(dst, src, count);
}
__must_check long strncpy_from_user(char *dst, const char __user *src,
				    long count);

/*
 * Return the size of a string (including the ending 0)
 *
 * Return 0 on exception, a value greater than N if too long
 */
extern int __strnlen_user(const char __user *sstr, int len);

static inline long strnlen_user(const char __user *src, long n)
{
	if (!access_ok(src, 1))
		return 0;
	return __strnlen_user(src, n);
}
__must_check long strnlen_user(const char __user *sstr, long len);

#endif /* _ASM_MICROBLAZE_UACCESS_H */
+0 −1
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ EXPORT_SYMBOL(_mcount);
 * Assembly functions that may be used (directly or indirectly) by modules
 */
EXPORT_SYMBOL(__copy_tofrom_user);
EXPORT_SYMBOL(__strncpy_user);

#ifdef CONFIG_OPT_LIB_ASM
EXPORT_SYMBOL(memcpy);
+0 −90
Original line number Diff line number Diff line
@@ -12,96 +12,6 @@
#include <linux/linkage.h>
#include <asm/page.h>

/*
 * int __strncpy_user(char *to, char *from, int len);
 *
 * Returns:
 *  -EFAULT  for an exception
 *  len      if we hit the buffer limit
 *  bytes copied
 */

	.text
.globl __strncpy_user;
.type  __strncpy_user, @function
.align 4;
__strncpy_user:

	/*
	 * r5 - to
	 * r6 - from
	 * r7 - len
	 * r3 - temp count
	 * r4 - temp val
	 */
	beqid	r7,3f
	addik	r3,r7,0		/* temp_count = len */
1:
	lbu	r4,r6,r0
	beqid	r4,2f
	sb	r4,r5,r0

	addik	r5,r5,1
	addik	r6,r6,1		/* delay slot */

	addik	r3,r3,-1
	bnei	r3,1b		/* break on len */
2:
	rsubk	r3,r3,r7	/* temp_count = len - temp_count */
3:
	rtsd	r15,8
	nop
	.size   __strncpy_user, . - __strncpy_user

	.section	.fixup, "ax"
	.align	2
4:
	brid	3b
	addik	r3,r0, -EFAULT

	.section	__ex_table, "a"
	.word	1b,4b

/*
 * int __strnlen_user(char __user *str, int maxlen);
 *
 * Returns:
 *  0 on error
 *  maxlen + 1  if no NUL byte found within maxlen bytes
 *  size of the string (including NUL byte)
 */

	.text
.globl __strnlen_user;
.type  __strnlen_user, @function
.align 4;
__strnlen_user:
	beqid	r6,3f
	addik	r3,r6,0
1:
	lbu	r4,r5,r0
	beqid	r4,2f		/* break on NUL */
	addik	r3,r3,-1	/* delay slot */

	bneid	r3,1b
	addik	r5,r5,1		/* delay slot */

	addik	r3,r3,-1	/* for break on len */
2:
	rsubk	r3,r3,r6
3:
	rtsd	r15,8
	nop
	.size   __strnlen_user, . - __strnlen_user

	.section	.fixup,"ax"
4:
	brid	3b
	addk	r3,r0,r0

	.section	__ex_table,"a"
	.word	1b,4b

/* Loop unrolling for __copy_tofrom_user */
#define COPY(offset)	\
1:	lwi	r4 , r6, 0x0000 + offset;	\