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