root/arch/arm/lib/getuser.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  *  linux/arch/arm/lib/getuser.S
   4  *
   5  *  Copyright (C) 2001 Russell King
   6  *
   7  *  Idea from x86 version, (C) Copyright 1998 Linus Torvalds
   8  *
   9  * These functions have a non-standard call interface to make them more
  10  * efficient, especially as they return an error value in addition to
  11  * the "real" return value.
  12  *
  13  * __get_user_X
  14  *
  15  * Inputs:      r0 contains the address
  16  *              r1 contains the address limit, which must be preserved
  17  * Outputs:     r0 is the error code
  18  *              r2, r3 contains the zero-extended value
  19  *              lr corrupted
  20  *
  21  * No other registers must be altered.  (see <asm/uaccess.h>
  22  * for specific ASM register usage).
  23  *
  24  * Note that ADDR_LIMIT is either 0 or 0xc0000000.
  25  * Note also that it is intended that __get_user_bad is not global.
  26  */
  27 #include <linux/linkage.h>
  28 #include <asm/assembler.h>
  29 #include <asm/errno.h>
  30 #include <asm/domain.h>
  31 
  32 ENTRY(__get_user_1)
  33         check_uaccess r0, 1, r1, r2, __get_user_bad
  34 1: TUSER(ldrb)  r2, [r0]
  35         mov     r0, #0
  36         ret     lr
  37 ENDPROC(__get_user_1)
  38 _ASM_NOKPROBE(__get_user_1)
  39 
  40 ENTRY(__get_user_2)
  41         check_uaccess r0, 2, r1, r2, __get_user_bad
  42 #if __LINUX_ARM_ARCH__ >= 6
  43 
  44 2: TUSER(ldrh)  r2, [r0]
  45 
  46 #else
  47 
  48 #ifdef CONFIG_CPU_USE_DOMAINS
  49 rb      .req    ip
  50 2:      ldrbt   r2, [r0], #1
  51 3:      ldrbt   rb, [r0], #0
  52 #else
  53 rb      .req    r0
  54 2:      ldrb    r2, [r0]
  55 3:      ldrb    rb, [r0, #1]
  56 #endif
  57 #ifndef __ARMEB__
  58         orr     r2, r2, rb, lsl #8
  59 #else
  60         orr     r2, rb, r2, lsl #8
  61 #endif
  62 
  63 #endif /* __LINUX_ARM_ARCH__ >= 6 */
  64 
  65         mov     r0, #0
  66         ret     lr
  67 ENDPROC(__get_user_2)
  68 _ASM_NOKPROBE(__get_user_2)
  69 
  70 ENTRY(__get_user_4)
  71         check_uaccess r0, 4, r1, r2, __get_user_bad
  72 4: TUSER(ldr)   r2, [r0]
  73         mov     r0, #0
  74         ret     lr
  75 ENDPROC(__get_user_4)
  76 _ASM_NOKPROBE(__get_user_4)
  77 
  78 ENTRY(__get_user_8)
  79         check_uaccess r0, 8, r1, r2, __get_user_bad8
  80 #ifdef CONFIG_THUMB2_KERNEL
  81 5: TUSER(ldr)   r2, [r0]
  82 6: TUSER(ldr)   r3, [r0, #4]
  83 #else
  84 5: TUSER(ldr)   r2, [r0], #4
  85 6: TUSER(ldr)   r3, [r0]
  86 #endif
  87         mov     r0, #0
  88         ret     lr
  89 ENDPROC(__get_user_8)
  90 _ASM_NOKPROBE(__get_user_8)
  91 
  92 #ifdef __ARMEB__
  93 ENTRY(__get_user_32t_8)
  94         check_uaccess r0, 8, r1, r2, __get_user_bad
  95 #ifdef CONFIG_CPU_USE_DOMAINS
  96         add     r0, r0, #4
  97 7:      ldrt    r2, [r0]
  98 #else
  99 7:      ldr     r2, [r0, #4]
 100 #endif
 101         mov     r0, #0
 102         ret     lr
 103 ENDPROC(__get_user_32t_8)
 104 _ASM_NOKPROBE(__get_user_32t_8)
 105 
 106 ENTRY(__get_user_64t_1)
 107         check_uaccess r0, 1, r1, r2, __get_user_bad8
 108 8: TUSER(ldrb)  r3, [r0]
 109         mov     r0, #0
 110         ret     lr
 111 ENDPROC(__get_user_64t_1)
 112 _ASM_NOKPROBE(__get_user_64t_1)
 113 
 114 ENTRY(__get_user_64t_2)
 115         check_uaccess r0, 2, r1, r2, __get_user_bad8
 116 #ifdef CONFIG_CPU_USE_DOMAINS
 117 rb      .req    ip
 118 9:      ldrbt   r3, [r0], #1
 119 10:     ldrbt   rb, [r0], #0
 120 #else
 121 rb      .req    r0
 122 9:      ldrb    r3, [r0]
 123 10:     ldrb    rb, [r0, #1]
 124 #endif
 125         orr     r3, rb, r3, lsl #8
 126         mov     r0, #0
 127         ret     lr
 128 ENDPROC(__get_user_64t_2)
 129 _ASM_NOKPROBE(__get_user_64t_2)
 130 
 131 ENTRY(__get_user_64t_4)
 132         check_uaccess r0, 4, r1, r2, __get_user_bad8
 133 11: TUSER(ldr)  r3, [r0]
 134         mov     r0, #0
 135         ret     lr
 136 ENDPROC(__get_user_64t_4)
 137 _ASM_NOKPROBE(__get_user_64t_4)
 138 #endif
 139 
 140 __get_user_bad8:
 141         mov     r3, #0
 142 __get_user_bad:
 143         mov     r2, #0
 144         mov     r0, #-EFAULT
 145         ret     lr
 146 ENDPROC(__get_user_bad)
 147 ENDPROC(__get_user_bad8)
 148 _ASM_NOKPROBE(__get_user_bad)
 149 _ASM_NOKPROBE(__get_user_bad8)
 150 
 151 .pushsection __ex_table, "a"
 152         .long   1b, __get_user_bad
 153         .long   2b, __get_user_bad
 154 #if __LINUX_ARM_ARCH__ < 6
 155         .long   3b, __get_user_bad
 156 #endif
 157         .long   4b, __get_user_bad
 158         .long   5b, __get_user_bad8
 159         .long   6b, __get_user_bad8
 160 #ifdef __ARMEB__
 161         .long   7b, __get_user_bad
 162         .long   8b, __get_user_bad8
 163         .long   9b, __get_user_bad8
 164         .long   10b, __get_user_bad8
 165         .long   11b, __get_user_bad8
 166 #endif
 167 .popsection

/* [<][>][^][v][top][bottom][index][help] */