Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *  linux/arch/arm/lib/getuser.S
0004  *
0005  *  Copyright (C) 2001 Russell King
0006  *
0007  *  Idea from x86 version, (C) Copyright 1998 Linus Torvalds
0008  *
0009  * These functions have a non-standard call interface to make them more
0010  * efficient, especially as they return an error value in addition to
0011  * the "real" return value.
0012  *
0013  * __get_user_X
0014  *
0015  * Inputs:  r0 contains the address
0016  *      r1 contains the address limit, which must be preserved
0017  * Outputs: r0 is the error code
0018  *      r2, r3 contains the zero-extended value
0019  *      lr corrupted
0020  *
0021  * No other registers must be altered.  (see <asm/uaccess.h>
0022  * for specific ASM register usage).
0023  *
0024  * Note that ADDR_LIMIT is either 0 or 0xc0000000.
0025  * Note also that it is intended that __get_user_bad is not global.
0026  */
0027 #include <linux/linkage.h>
0028 #include <asm/assembler.h>
0029 #include <asm/errno.h>
0030 #include <asm/domain.h>
0031 
0032 ENTRY(__get_user_1)
0033     check_uaccess r0, 1, r1, r2, __get_user_bad
0034 1: TUSER(ldrb)  r2, [r0]
0035     mov r0, #0
0036     ret lr
0037 ENDPROC(__get_user_1)
0038 _ASM_NOKPROBE(__get_user_1)
0039 
0040 ENTRY(__get_user_2)
0041     check_uaccess r0, 2, r1, r2, __get_user_bad
0042 #if __LINUX_ARM_ARCH__ >= 6
0043 
0044 2: TUSER(ldrh)  r2, [r0]
0045 
0046 #else
0047 
0048 #ifdef CONFIG_CPU_USE_DOMAINS
0049 rb  .req    ip
0050 2:  ldrbt   r2, [r0], #1
0051 3:  ldrbt   rb, [r0], #0
0052 #else
0053 rb  .req    r0
0054 2:  ldrb    r2, [r0]
0055 3:  ldrb    rb, [r0, #1]
0056 #endif
0057 #ifndef __ARMEB__
0058     orr r2, r2, rb, lsl #8
0059 #else
0060     orr r2, rb, r2, lsl #8
0061 #endif
0062 
0063 #endif /* __LINUX_ARM_ARCH__ >= 6 */
0064 
0065     mov r0, #0
0066     ret lr
0067 ENDPROC(__get_user_2)
0068 _ASM_NOKPROBE(__get_user_2)
0069 
0070 ENTRY(__get_user_4)
0071     check_uaccess r0, 4, r1, r2, __get_user_bad
0072 4: TUSER(ldr)   r2, [r0]
0073     mov r0, #0
0074     ret lr
0075 ENDPROC(__get_user_4)
0076 _ASM_NOKPROBE(__get_user_4)
0077 
0078 ENTRY(__get_user_8)
0079     check_uaccess r0, 8, r1, r2, __get_user_bad8
0080 #ifdef CONFIG_THUMB2_KERNEL
0081 5: TUSER(ldr)   r2, [r0]
0082 6: TUSER(ldr)   r3, [r0, #4]
0083 #else
0084 5: TUSER(ldr)   r2, [r0], #4
0085 6: TUSER(ldr)   r3, [r0]
0086 #endif
0087     mov r0, #0
0088     ret lr
0089 ENDPROC(__get_user_8)
0090 _ASM_NOKPROBE(__get_user_8)
0091 
0092 #ifdef __ARMEB__
0093 ENTRY(__get_user_32t_8)
0094     check_uaccess r0, 8, r1, r2, __get_user_bad
0095 #ifdef CONFIG_CPU_USE_DOMAINS
0096     add r0, r0, #4
0097 7:  ldrt    r2, [r0]
0098 #else
0099 7:  ldr r2, [r0, #4]
0100 #endif
0101     mov r0, #0
0102     ret lr
0103 ENDPROC(__get_user_32t_8)
0104 _ASM_NOKPROBE(__get_user_32t_8)
0105 
0106 ENTRY(__get_user_64t_1)
0107     check_uaccess r0, 1, r1, r2, __get_user_bad8
0108 8: TUSER(ldrb)  r3, [r0]
0109     mov r0, #0
0110     ret lr
0111 ENDPROC(__get_user_64t_1)
0112 _ASM_NOKPROBE(__get_user_64t_1)
0113 
0114 ENTRY(__get_user_64t_2)
0115     check_uaccess r0, 2, r1, r2, __get_user_bad8
0116 #ifdef CONFIG_CPU_USE_DOMAINS
0117 rb  .req    ip
0118 9:  ldrbt   r3, [r0], #1
0119 10: ldrbt   rb, [r0], #0
0120 #else
0121 rb  .req    r0
0122 9:  ldrb    r3, [r0]
0123 10: ldrb    rb, [r0, #1]
0124 #endif
0125     orr r3, rb, r3, lsl #8
0126     mov r0, #0
0127     ret lr
0128 ENDPROC(__get_user_64t_2)
0129 _ASM_NOKPROBE(__get_user_64t_2)
0130 
0131 ENTRY(__get_user_64t_4)
0132     check_uaccess r0, 4, r1, r2, __get_user_bad8
0133 11: TUSER(ldr)  r3, [r0]
0134     mov r0, #0
0135     ret lr
0136 ENDPROC(__get_user_64t_4)
0137 _ASM_NOKPROBE(__get_user_64t_4)
0138 #endif
0139 
0140 __get_user_bad8:
0141     mov r3, #0
0142 __get_user_bad:
0143     mov r2, #0
0144     mov r0, #-EFAULT
0145     ret lr
0146 ENDPROC(__get_user_bad)
0147 ENDPROC(__get_user_bad8)
0148 _ASM_NOKPROBE(__get_user_bad)
0149 _ASM_NOKPROBE(__get_user_bad8)
0150 
0151 .pushsection __ex_table, "a"
0152     .long   1b, __get_user_bad
0153     .long   2b, __get_user_bad
0154 #if __LINUX_ARM_ARCH__ < 6
0155     .long   3b, __get_user_bad
0156 #endif
0157     .long   4b, __get_user_bad
0158     .long   5b, __get_user_bad8
0159     .long   6b, __get_user_bad8
0160 #ifdef __ARMEB__
0161     .long   7b, __get_user_bad
0162     .long   8b, __get_user_bad8
0163     .long   9b, __get_user_bad8
0164     .long   10b, __get_user_bad8
0165     .long   11b, __get_user_bad8
0166 #endif
0167 .popsection