mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	Remove the csky implemenation of strncpy/strnlen and instead use the generic versions. The csky 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: Christoph Hellwig <hch@lst.de> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
		
			
				
	
	
		
			214 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0
 | 
						|
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
 | 
						|
 | 
						|
#include <linux/uaccess.h>
 | 
						|
#include <linux/types.h>
 | 
						|
 | 
						|
unsigned long raw_copy_from_user(void *to, const void *from,
 | 
						|
			unsigned long n)
 | 
						|
{
 | 
						|
	int tmp, nsave;
 | 
						|
 | 
						|
	__asm__ __volatile__(
 | 
						|
	"0:     cmpnei  %1, 0           \n"
 | 
						|
	"       bf      7f              \n"
 | 
						|
	"       mov     %3, %1          \n"
 | 
						|
	"       or      %3, %2          \n"
 | 
						|
	"       andi    %3, 3           \n"
 | 
						|
	"       cmpnei  %3, 0           \n"
 | 
						|
	"       bf      1f              \n"
 | 
						|
	"       br      5f              \n"
 | 
						|
	"1:     cmplti  %0, 16          \n"
 | 
						|
	"       bt      3f              \n"
 | 
						|
	"2:     ldw     %3, (%2, 0)     \n"
 | 
						|
	"10:    ldw     %4, (%2, 4)     \n"
 | 
						|
	"       stw     %3, (%1, 0)     \n"
 | 
						|
	"       stw     %4, (%1, 4)     \n"
 | 
						|
	"11:    ldw     %3, (%2, 8)     \n"
 | 
						|
	"12:    ldw     %4, (%2, 12)    \n"
 | 
						|
	"       stw     %3, (%1, 8)     \n"
 | 
						|
	"       stw     %4, (%1, 12)    \n"
 | 
						|
	"       addi    %2, 16          \n"
 | 
						|
	"       addi    %1, 16          \n"
 | 
						|
	"       subi    %0, 16          \n"
 | 
						|
	"       br      1b              \n"
 | 
						|
	"3:     cmplti  %0, 4           \n"
 | 
						|
	"       bt      5f              \n"
 | 
						|
	"4:     ldw     %3, (%2, 0)     \n"
 | 
						|
	"       stw     %3, (%1, 0)     \n"
 | 
						|
	"       addi    %2, 4           \n"
 | 
						|
	"       addi    %1, 4           \n"
 | 
						|
	"       subi    %0, 4           \n"
 | 
						|
	"       br      3b              \n"
 | 
						|
	"5:     cmpnei  %0, 0           \n"
 | 
						|
	"       bf      7f              \n"
 | 
						|
	"6:     ldb     %3, (%2, 0)     \n"
 | 
						|
	"       stb     %3, (%1, 0)     \n"
 | 
						|
	"       addi    %2,  1          \n"
 | 
						|
	"       addi    %1,  1          \n"
 | 
						|
	"       subi    %0,  1          \n"
 | 
						|
	"       br      5b              \n"
 | 
						|
	"8:     stw     %3, (%1, 0)     \n"
 | 
						|
	"       subi    %0, 4           \n"
 | 
						|
	"       bf      7f              \n"
 | 
						|
	"9:     subi    %0, 8           \n"
 | 
						|
	"       bf      7f              \n"
 | 
						|
	"13:    stw     %3, (%1, 8)     \n"
 | 
						|
	"       subi    %0, 12          \n"
 | 
						|
	"       bf      7f              \n"
 | 
						|
	".section __ex_table, \"a\"     \n"
 | 
						|
	".align   2                     \n"
 | 
						|
	".long    2b, 7f                \n"
 | 
						|
	".long    4b, 7f                \n"
 | 
						|
	".long    6b, 7f                \n"
 | 
						|
	".long   10b, 8b                \n"
 | 
						|
	".long   11b, 9b                \n"
 | 
						|
	".long   12b,13b                \n"
 | 
						|
	".previous                      \n"
 | 
						|
	"7:                             \n"
 | 
						|
	: "=r"(n), "=r"(to), "=r"(from), "=r"(nsave),
 | 
						|
	  "=r"(tmp)
 | 
						|
	: "0"(n), "1"(to), "2"(from)
 | 
						|
	: "memory");
 | 
						|
 | 
						|
	return n;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(raw_copy_from_user);
 | 
						|
 | 
						|
unsigned long raw_copy_to_user(void *to, const void *from,
 | 
						|
			unsigned long n)
 | 
						|
{
 | 
						|
	int w0, w1, w2, w3;
 | 
						|
 | 
						|
	__asm__ __volatile__(
 | 
						|
	"0:     cmpnei  %1, 0           \n"
 | 
						|
	"       bf      8f              \n"
 | 
						|
	"       mov     %3, %1          \n"
 | 
						|
	"       or      %3, %2          \n"
 | 
						|
	"       andi    %3, 3           \n"
 | 
						|
	"       cmpnei  %3, 0           \n"
 | 
						|
	"       bf      1f              \n"
 | 
						|
	"       br      5f              \n"
 | 
						|
	"1:     cmplti  %0, 16          \n" /* 4W */
 | 
						|
	"       bt      3f              \n"
 | 
						|
	"       ldw     %3, (%2, 0)     \n"
 | 
						|
	"       ldw     %4, (%2, 4)     \n"
 | 
						|
	"       ldw     %5, (%2, 8)     \n"
 | 
						|
	"       ldw     %6, (%2, 12)    \n"
 | 
						|
	"2:     stw     %3, (%1, 0)     \n"
 | 
						|
	"9:     stw     %4, (%1, 4)     \n"
 | 
						|
	"10:    stw     %5, (%1, 8)     \n"
 | 
						|
	"11:    stw     %6, (%1, 12)    \n"
 | 
						|
	"       addi    %2, 16          \n"
 | 
						|
	"       addi    %1, 16          \n"
 | 
						|
	"       subi    %0, 16          \n"
 | 
						|
	"       br      1b              \n"
 | 
						|
	"3:     cmplti  %0, 4           \n" /* 1W */
 | 
						|
	"       bt      5f              \n"
 | 
						|
	"       ldw     %3, (%2, 0)     \n"
 | 
						|
	"4:     stw     %3, (%1, 0)     \n"
 | 
						|
	"       addi    %2, 4           \n"
 | 
						|
	"       addi    %1, 4           \n"
 | 
						|
	"       subi    %0, 4           \n"
 | 
						|
	"       br      3b              \n"
 | 
						|
	"5:     cmpnei  %0, 0           \n"  /* 1B */
 | 
						|
	"       bf      13f             \n"
 | 
						|
	"       ldb     %3, (%2, 0)     \n"
 | 
						|
	"6:     stb     %3, (%1, 0)     \n"
 | 
						|
	"       addi    %2,  1          \n"
 | 
						|
	"       addi    %1,  1          \n"
 | 
						|
	"       subi    %0,  1          \n"
 | 
						|
	"       br      5b              \n"
 | 
						|
	"7:     subi	%0,  4          \n"
 | 
						|
	"8:     subi	%0,  4          \n"
 | 
						|
	"12:    subi	%0,  4          \n"
 | 
						|
	"       br      13f             \n"
 | 
						|
	".section __ex_table, \"a\"     \n"
 | 
						|
	".align   2                     \n"
 | 
						|
	".long    2b, 13f               \n"
 | 
						|
	".long    4b, 13f               \n"
 | 
						|
	".long    6b, 13f               \n"
 | 
						|
	".long    9b, 12b               \n"
 | 
						|
	".long   10b, 8b                \n"
 | 
						|
	".long   11b, 7b                \n"
 | 
						|
	".previous                      \n"
 | 
						|
	"13:                            \n"
 | 
						|
	: "=r"(n), "=r"(to), "=r"(from), "=r"(w0),
 | 
						|
	  "=r"(w1), "=r"(w2), "=r"(w3)
 | 
						|
	: "0"(n), "1"(to), "2"(from)
 | 
						|
	: "memory");
 | 
						|
 | 
						|
	return n;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(raw_copy_to_user);
 | 
						|
 | 
						|
/*
 | 
						|
 * __clear_user: - Zero a block of memory in user space, with less checking.
 | 
						|
 * @to:   Destination address, in user space.
 | 
						|
 * @n:    Number of bytes to zero.
 | 
						|
 *
 | 
						|
 * Zero a block of memory in user space.  Caller must check
 | 
						|
 * the specified block with access_ok() before calling this function.
 | 
						|
 *
 | 
						|
 * Returns number of bytes that could not be cleared.
 | 
						|
 * On success, this will be zero.
 | 
						|
 */
 | 
						|
unsigned long
 | 
						|
__clear_user(void __user *to, unsigned long n)
 | 
						|
{
 | 
						|
	int data, value, tmp;
 | 
						|
 | 
						|
	__asm__ __volatile__(
 | 
						|
	"0:     cmpnei  %1, 0           \n"
 | 
						|
	"       bf      7f              \n"
 | 
						|
	"       mov     %3, %1          \n"
 | 
						|
	"       andi    %3, 3           \n"
 | 
						|
	"       cmpnei  %3, 0           \n"
 | 
						|
	"       bf      1f              \n"
 | 
						|
	"       br      5f              \n"
 | 
						|
	"1:     cmplti  %0, 32          \n" /* 4W */
 | 
						|
	"       bt      3f              \n"
 | 
						|
	"8:     stw     %2, (%1, 0)     \n"
 | 
						|
	"10:    stw     %2, (%1, 4)     \n"
 | 
						|
	"11:    stw     %2, (%1, 8)     \n"
 | 
						|
	"12:    stw     %2, (%1, 12)    \n"
 | 
						|
	"13:    stw     %2, (%1, 16)    \n"
 | 
						|
	"14:    stw     %2, (%1, 20)    \n"
 | 
						|
	"15:    stw     %2, (%1, 24)    \n"
 | 
						|
	"16:    stw     %2, (%1, 28)    \n"
 | 
						|
	"       addi    %1, 32          \n"
 | 
						|
	"       subi    %0, 32          \n"
 | 
						|
	"       br      1b              \n"
 | 
						|
	"3:     cmplti  %0, 4           \n" /* 1W */
 | 
						|
	"       bt      5f              \n"
 | 
						|
	"4:     stw     %2, (%1, 0)     \n"
 | 
						|
	"       addi    %1, 4           \n"
 | 
						|
	"       subi    %0, 4           \n"
 | 
						|
	"       br      3b              \n"
 | 
						|
	"5:     cmpnei  %0, 0           \n" /* 1B */
 | 
						|
	"9:     bf      7f              \n"
 | 
						|
	"6:     stb     %2, (%1, 0)     \n"
 | 
						|
	"       addi    %1,  1          \n"
 | 
						|
	"       subi    %0,  1          \n"
 | 
						|
	"       br      5b              \n"
 | 
						|
	".section __ex_table,\"a\"      \n"
 | 
						|
	".align   2                     \n"
 | 
						|
	".long    8b, 9b                \n"
 | 
						|
	".long    10b, 9b               \n"
 | 
						|
	".long    11b, 9b               \n"
 | 
						|
	".long    12b, 9b               \n"
 | 
						|
	".long    13b, 9b               \n"
 | 
						|
	".long    14b, 9b               \n"
 | 
						|
	".long    15b, 9b               \n"
 | 
						|
	".long    16b, 9b               \n"
 | 
						|
	".long    4b, 9b                \n"
 | 
						|
	".long    6b, 9b                \n"
 | 
						|
	".previous                      \n"
 | 
						|
	"7:                             \n"
 | 
						|
	: "=r"(n), "=r" (data), "=r"(value), "=r"(tmp)
 | 
						|
	: "0"(n), "1"(to), "2"(0)
 | 
						|
	: "memory");
 | 
						|
 | 
						|
	return n;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(__clear_user);
 |