Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
48SYM_FUNC_START(__put_user_1)
49 check_range size=1
50 ASM_STAC
511: movb %al,(%_ASM_CX)
52 xor %ecx,%ecx
53 ASM_CLAC
54 RET
55SYM_FUNC_END(__put_user_1)
56EXPORT_SYMBOL(__put_user_1)
57
58SYM_FUNC_START(__put_user_nocheck_1)
59 ENDBR
60 ASM_STAC
612: movb %al,(%_ASM_CX)
62 xor %ecx,%ecx
63 ASM_CLAC
64 RET
65SYM_FUNC_END(__put_user_nocheck_1)
66EXPORT_SYMBOL(__put_user_nocheck_1)
67
68SYM_FUNC_START(__put_user_2)
69 check_range size=2
70 ASM_STAC
713: movw %ax,(%_ASM_CX)
72 xor %ecx,%ecx
73 ASM_CLAC
74 RET
75SYM_FUNC_END(__put_user_2)
76EXPORT_SYMBOL(__put_user_2)
77
78SYM_FUNC_START(__put_user_nocheck_2)
79 ENDBR
80 ASM_STAC
814: movw %ax,(%_ASM_CX)
82 xor %ecx,%ecx
83 ASM_CLAC
84 RET
85SYM_FUNC_END(__put_user_nocheck_2)
86EXPORT_SYMBOL(__put_user_nocheck_2)
87
88SYM_FUNC_START(__put_user_4)
89 check_range size=4
90 ASM_STAC
915: movl %eax,(%_ASM_CX)
92 xor %ecx,%ecx
93 ASM_CLAC
94 RET
95SYM_FUNC_END(__put_user_4)
96EXPORT_SYMBOL(__put_user_4)
97
98SYM_FUNC_START(__put_user_nocheck_4)
99 ENDBR
100 ASM_STAC
1016: movl %eax,(%_ASM_CX)
102 xor %ecx,%ecx
103 ASM_CLAC
104 RET
105SYM_FUNC_END(__put_user_nocheck_4)
106EXPORT_SYMBOL(__put_user_nocheck_4)
107
108SYM_FUNC_START(__put_user_8)
109 check_range size=8
110 ASM_STAC
1117: mov %_ASM_AX,(%_ASM_CX)
112#ifdef CONFIG_X86_32
1138: movl %edx,4(%_ASM_CX)
114#endif
115 xor %ecx,%ecx
116 ASM_CLAC
117 RET
118SYM_FUNC_END(__put_user_8)
119EXPORT_SYMBOL(__put_user_8)
120
121SYM_FUNC_START(__put_user_nocheck_8)
122 ENDBR
123 ASM_STAC
1249: mov %_ASM_AX,(%_ASM_CX)
125#ifdef CONFIG_X86_32
12610: movl %edx,4(%_ASM_CX)
127#endif
128 xor %ecx,%ecx
129 ASM_CLAC
130 RET
131SYM_FUNC_END(__put_user_nocheck_8)
132EXPORT_SYMBOL(__put_user_nocheck_8)
133
134SYM_CODE_START_LOCAL(__put_user_handle_exception)
135 ASM_CLAC
136.Lbad_put_user:
137 movl $-EFAULT,%ecx
138 RET
139SYM_CODE_END(__put_user_handle_exception)
140
141 _ASM_EXTABLE(1b, __put_user_handle_exception)
142 _ASM_EXTABLE(2b, __put_user_handle_exception)
143 _ASM_EXTABLE(3b, __put_user_handle_exception)
144 _ASM_EXTABLE(4b, __put_user_handle_exception)
145 _ASM_EXTABLE(5b, __put_user_handle_exception)
146 _ASM_EXTABLE(6b, __put_user_handle_exception)
147 _ASM_EXTABLE(7b, __put_user_handle_exception)
148 _ASM_EXTABLE(9b, __put_user_handle_exception)
149#ifdef CONFIG_X86_32
150 _ASM_EXTABLE(8b, __put_user_handle_exception)
151 _ASM_EXTABLE(10b, __put_user_handle_exception)
152#endif