Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / arch / arm / lib / putuser.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  *  linux/arch/arm/lib/putuser.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
10  * them more efficient, especially as they return an error
11  * value in addition to the "real" return value.
12  *
13  * __put_user_X
14  *
15  * Inputs:      r0 contains the address
16  *              r1 contains the address limit, which must be preserved
17  *              r2, r3 contains the value
18  * Outputs:     r0 is the error code
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 __put_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(__put_user_1)
33         check_uaccess r0, 1, r1, ip, __put_user_bad
34 1: TUSER(strb)  r2, [r0]
35         mov     r0, #0
36         ret     lr
37 ENDPROC(__put_user_1)
38
39 ENTRY(__put_user_2)
40         check_uaccess r0, 2, r1, ip, __put_user_bad
41 #if __LINUX_ARM_ARCH__ >= 6
42
43 2: TUSER(strh)  r2, [r0]
44
45 #else
46
47         mov     ip, r2, lsr #8
48 #ifndef __ARMEB__
49 2: TUSER(strb)  r2, [r0], #1
50 3: TUSER(strb)  ip, [r0]
51 #else
52 2: TUSER(strb)  ip, [r0], #1
53 3: TUSER(strb)  r2, [r0]
54 #endif
55
56 #endif /* __LINUX_ARM_ARCH__ >= 6 */
57         mov     r0, #0
58         ret     lr
59 ENDPROC(__put_user_2)
60
61 ENTRY(__put_user_4)
62         check_uaccess r0, 4, r1, ip, __put_user_bad
63 4: TUSER(str)   r2, [r0]
64         mov     r0, #0
65         ret     lr
66 ENDPROC(__put_user_4)
67
68 ENTRY(__put_user_8)
69         check_uaccess r0, 8, r1, ip, __put_user_bad
70 #ifdef CONFIG_THUMB2_KERNEL
71 5: TUSER(str)   r2, [r0]
72 6: TUSER(str)   r3, [r0, #4]
73 #else
74 5: TUSER(str)   r2, [r0], #4
75 6: TUSER(str)   r3, [r0]
76 #endif
77         mov     r0, #0
78         ret     lr
79 ENDPROC(__put_user_8)
80
81 __put_user_bad:
82         mov     r0, #-EFAULT
83         ret     lr
84 ENDPROC(__put_user_bad)
85
86 .pushsection __ex_table, "a"
87         .long   1b, __put_user_bad
88         .long   2b, __put_user_bad
89 #if __LINUX_ARM_ARCH__ < 6
90         .long   3b, __put_user_bad
91 #endif
92         .long   4b, __put_user_bad
93         .long   5b, __put_user_bad
94         .long   6b, __put_user_bad
95 .popsection