Back to home page

LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 1996, 1999 by Ralf Baechle
0007  * Copyright (C) 2011 MIPS Technologies, Inc.
0008  */
0009 #include <linux/errno.h>
0010 #include <asm/asm.h>
0011 #include <asm/asm-offsets.h>
0012 #include <asm/regdef.h>
0013 
0014 #define EX(insn,reg,addr,handler)           \
0015 9:  insn    reg, addr;              \
0016     .section __ex_table,"a";            \
0017     PTR 9b, handler;                \
0018     .previous
0019 
0020 /*
0021  * Returns: -EFAULT if exception before terminator, N if the entire
0022  * buffer filled, else strlen.
0023  */
0024 
0025 /*
0026  * Ugly special case have to check: we might get passed a user space
0027  * pointer which wraps into the kernel space.  We don't deal with that.  If
0028  * it happens at most some bytes of the exceptions handlers will be copied.
0029  */
0030 
0031     .macro __BUILD_STRNCPY_ASM func
0032 LEAF(__strncpy_from_\func\()_asm)
0033     LONG_L      v0, TI_ADDR_LIMIT($28)  # pointer ok?
0034     and     v0, a1
0035     bnez        v0, .Lfault\@
0036 
0037 FEXPORT(__strncpy_from_\func\()_nocheck_asm)
0038     move        t0, zero
0039     move        v1, a1
0040 .ifeqs "\func","kernel"
0041 1:  EX(lbu, v0, (v1), .Lfault\@)
0042 .else
0043 1:  EX(lbue, v0, (v1), .Lfault\@)
0044 .endif
0045     PTR_ADDIU   v1, 1
0046     R10KCBARRIER(0(ra))
0047     sb      v0, (a0)
0048     beqz        v0, 2f
0049     PTR_ADDIU   t0, 1
0050     PTR_ADDIU   a0, 1
0051     bne     t0, a2, 1b
0052 2:  PTR_ADDU    v0, a1, t0
0053     xor     v0, a1
0054     bltz        v0, .Lfault\@
0055     move        v0, t0
0056     jr      ra          # return n
0057     END(__strncpy_from_\func\()_asm)
0058 
0059 .Lfault\@:
0060     li      v0, -EFAULT
0061     jr      ra
0062 
0063     .section    __ex_table,"a"
0064     PTR     1b, .Lfault\@
0065     .previous
0066 
0067     .endm
0068 
0069 #ifndef CONFIG_EVA
0070     /* Set aliases */
0071     .global __strncpy_from_user_asm
0072     .global __strncpy_from_user_nocheck_asm
0073     .set __strncpy_from_user_asm, __strncpy_from_kernel_asm
0074     .set __strncpy_from_user_nocheck_asm, __strncpy_from_kernel_nocheck_asm
0075 #endif
0076 
0077 __BUILD_STRNCPY_ASM kernel
0078 
0079 #ifdef CONFIG_EVA
0080     .set push
0081     .set eva
0082 __BUILD_STRNCPY_ASM user
0083     .set pop
0084 #endif