Merge tag 'x86-urgent-2023-09-17' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-rpi.git] / arch / x86 / lib / putuser.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * __put_user functions.
4  *
5  * (C) Copyright 2005 Linus Torvalds
6  * (C) Copyright 2005 Andi Kleen
7  * (C) Copyright 2008 Glauber Costa
8  *
9  * These functions have a non-standard call interface
10  * to make them more efficient, especially as they
11  * return an error value in addition to the "real"
12  * return value.
13  */
14 #include <linux/linkage.h>
15 #include <asm/thread_info.h>
16 #include <asm/errno.h>
17 #include <asm/asm.h>
18 #include <asm/smap.h>
19 #include <asm/export.h>
20
21
22 /*
23  * __put_user_X
24  *
25  * Inputs:      %eax[:%edx] contains the data
26  *              %ecx contains the address
27  *
28  * Outputs:     %ecx is error code (0 or -EFAULT)
29  *
30  * Clobbers:    %ebx needed for task pointer
31  *
32  * These functions should not modify any other registers,
33  * as they get called from within inline assembly.
34  */
35
36 .macro check_range size:req
37 .if IS_ENABLED(CONFIG_X86_64)
38         mov %rcx, %rbx
39         sar $63, %rbx
40         or %rbx, %rcx
41 .else
42         cmp $TASK_SIZE_MAX-\size+1, %ecx
43         jae .Lbad_put_user
44 .endif
45 .endm
46
47 .text
48 SYM_FUNC_START(__put_user_1)
49         check_range size=1
50         ASM_STAC
51 1:      movb %al,(%_ASM_CX)
52         xor %ecx,%ecx
53         ASM_CLAC
54         RET
55 SYM_FUNC_END(__put_user_1)
56 EXPORT_SYMBOL(__put_user_1)
57
58 SYM_FUNC_START(__put_user_nocheck_1)
59         ASM_STAC
60 2:      movb %al,(%_ASM_CX)
61         xor %ecx,%ecx
62         ASM_CLAC
63         RET
64 SYM_FUNC_END(__put_user_nocheck_1)
65 EXPORT_SYMBOL(__put_user_nocheck_1)
66
67 SYM_FUNC_START(__put_user_2)
68         check_range size=2
69         ASM_STAC
70 3:      movw %ax,(%_ASM_CX)
71         xor %ecx,%ecx
72         ASM_CLAC
73         RET
74 SYM_FUNC_END(__put_user_2)
75 EXPORT_SYMBOL(__put_user_2)
76
77 SYM_FUNC_START(__put_user_nocheck_2)
78         ASM_STAC
79 4:      movw %ax,(%_ASM_CX)
80         xor %ecx,%ecx
81         ASM_CLAC
82         RET
83 SYM_FUNC_END(__put_user_nocheck_2)
84 EXPORT_SYMBOL(__put_user_nocheck_2)
85
86 SYM_FUNC_START(__put_user_4)
87         check_range size=4
88         ASM_STAC
89 5:      movl %eax,(%_ASM_CX)
90         xor %ecx,%ecx
91         ASM_CLAC
92         RET
93 SYM_FUNC_END(__put_user_4)
94 EXPORT_SYMBOL(__put_user_4)
95
96 SYM_FUNC_START(__put_user_nocheck_4)
97         ASM_STAC
98 6:      movl %eax,(%_ASM_CX)
99         xor %ecx,%ecx
100         ASM_CLAC
101         RET
102 SYM_FUNC_END(__put_user_nocheck_4)
103 EXPORT_SYMBOL(__put_user_nocheck_4)
104
105 SYM_FUNC_START(__put_user_8)
106         check_range size=8
107         ASM_STAC
108 7:      mov %_ASM_AX,(%_ASM_CX)
109 #ifdef CONFIG_X86_32
110 8:      movl %edx,4(%_ASM_CX)
111 #endif
112         xor %ecx,%ecx
113         ASM_CLAC
114         RET
115 SYM_FUNC_END(__put_user_8)
116 EXPORT_SYMBOL(__put_user_8)
117
118 SYM_FUNC_START(__put_user_nocheck_8)
119         ASM_STAC
120 9:      mov %_ASM_AX,(%_ASM_CX)
121 #ifdef CONFIG_X86_32
122 10:     movl %edx,4(%_ASM_CX)
123 #endif
124         xor %ecx,%ecx
125         ASM_CLAC
126         RET
127 SYM_FUNC_END(__put_user_nocheck_8)
128 EXPORT_SYMBOL(__put_user_nocheck_8)
129
130 SYM_CODE_START_LOCAL(__put_user_handle_exception)
131         ASM_CLAC
132 .Lbad_put_user:
133         movl $-EFAULT,%ecx
134         RET
135 SYM_CODE_END(__put_user_handle_exception)
136
137         _ASM_EXTABLE(1b, __put_user_handle_exception)
138         _ASM_EXTABLE(2b, __put_user_handle_exception)
139         _ASM_EXTABLE(3b, __put_user_handle_exception)
140         _ASM_EXTABLE(4b, __put_user_handle_exception)
141         _ASM_EXTABLE(5b, __put_user_handle_exception)
142         _ASM_EXTABLE(6b, __put_user_handle_exception)
143         _ASM_EXTABLE(7b, __put_user_handle_exception)
144         _ASM_EXTABLE(9b, __put_user_handle_exception)
145 #ifdef CONFIG_X86_32
146         _ASM_EXTABLE(8b, __put_user_handle_exception)
147         _ASM_EXTABLE(10b, __put_user_handle_exception)
148 #endif