Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1da177e4 LT |
2 | /* |
3 | * __get_user functions. | |
4 | * | |
5 | * (C) Copyright 1998 Linus Torvalds | |
6 | * (C) Copyright 2005 Andi Kleen | |
6c2d4586 | 7 | * (C) Copyright 2008 Glauber Costa |
1da177e4 LT |
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 | ||
15 | /* | |
16 | * __get_user_X | |
17 | * | |
6c2d4586 | 18 | * Inputs: %[r|e]ax contains the address. |
1da177e4 | 19 | * |
6c2d4586 GC |
20 | * Outputs: %[r|e]ax is error code (0 or -EFAULT) |
21 | * %[r|e]dx contains zero-extended value | |
96477b4c | 22 | * %ecx contains the high half for 32-bit __get_user_8 |
6c2d4586 | 23 | * |
1da177e4 LT |
24 | * |
25 | * These functions should not modify any other registers, | |
26 | * as they get called from within inline assembly. | |
27 | */ | |
28 | ||
29 | #include <linux/linkage.h> | |
0341c14d | 30 | #include <asm/page_types.h> |
1da177e4 | 31 | #include <asm/errno.h> |
e2d5df93 | 32 | #include <asm/asm-offsets.h> |
1da177e4 | 33 | #include <asm/thread_info.h> |
40faf463 | 34 | #include <asm/asm.h> |
63bcff2a | 35 | #include <asm/smap.h> |
784d5699 | 36 | #include <asm/export.h> |
1da177e4 LT |
37 | |
38 | .text | |
8d379dad | 39 | ENTRY(__get_user_1) |
13d4ea09 AL |
40 | mov PER_CPU_VAR(current_task), %_ASM_DX |
41 | cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX | |
1da177e4 | 42 | jae bad_get_user |
63bcff2a | 43 | ASM_STAC |
16640165 | 44 | 1: movzbl (%_ASM_AX),%edx |
ef8c1a2d | 45 | xor %eax,%eax |
63bcff2a | 46 | ASM_CLAC |
1da177e4 | 47 | ret |
8d379dad | 48 | ENDPROC(__get_user_1) |
784d5699 | 49 | EXPORT_SYMBOL(__get_user_1) |
1da177e4 | 50 | |
8d379dad | 51 | ENTRY(__get_user_2) |
40faf463 | 52 | add $1,%_ASM_AX |
92628753 | 53 | jc bad_get_user |
13d4ea09 AL |
54 | mov PER_CPU_VAR(current_task), %_ASM_DX |
55 | cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX | |
92628753 | 56 | jae bad_get_user |
63bcff2a | 57 | ASM_STAC |
40faf463 | 58 | 2: movzwl -1(%_ASM_AX),%edx |
ef8c1a2d | 59 | xor %eax,%eax |
63bcff2a | 60 | ASM_CLAC |
1da177e4 | 61 | ret |
8d379dad | 62 | ENDPROC(__get_user_2) |
784d5699 | 63 | EXPORT_SYMBOL(__get_user_2) |
1da177e4 | 64 | |
8d379dad | 65 | ENTRY(__get_user_4) |
40faf463 | 66 | add $3,%_ASM_AX |
92628753 | 67 | jc bad_get_user |
13d4ea09 AL |
68 | mov PER_CPU_VAR(current_task), %_ASM_DX |
69 | cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX | |
92628753 | 70 | jae bad_get_user |
63bcff2a | 71 | ASM_STAC |
16640165 | 72 | 3: movl -3(%_ASM_AX),%edx |
ef8c1a2d | 73 | xor %eax,%eax |
63bcff2a | 74 | ASM_CLAC |
1da177e4 | 75 | ret |
8d379dad | 76 | ENDPROC(__get_user_4) |
784d5699 | 77 | EXPORT_SYMBOL(__get_user_4) |
1da177e4 | 78 | |
8d379dad | 79 | ENTRY(__get_user_8) |
96477b4c | 80 | #ifdef CONFIG_X86_64 |
40faf463 | 81 | add $7,%_ASM_AX |
92628753 | 82 | jc bad_get_user |
13d4ea09 AL |
83 | mov PER_CPU_VAR(current_task), %_ASM_DX |
84 | cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX | |
96477b4c | 85 | jae bad_get_user |
63bcff2a | 86 | ASM_STAC |
16640165 | 87 | 4: movq -7(%_ASM_AX),%rdx |
ef8c1a2d | 88 | xor %eax,%eax |
63bcff2a | 89 | ASM_CLAC |
1da177e4 | 90 | ret |
96477b4c VS |
91 | #else |
92 | add $7,%_ASM_AX | |
93 | jc bad_get_user_8 | |
13d4ea09 AL |
94 | mov PER_CPU_VAR(current_task), %_ASM_DX |
95 | cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX | |
96477b4c VS |
96 | jae bad_get_user_8 |
97 | ASM_STAC | |
16640165 PA |
98 | 4: movl -7(%_ASM_AX),%edx |
99 | 5: movl -3(%_ASM_AX),%ecx | |
96477b4c VS |
100 | xor %eax,%eax |
101 | ASM_CLAC | |
102 | ret | |
103 | #endif | |
8d379dad | 104 | ENDPROC(__get_user_8) |
784d5699 | 105 | EXPORT_SYMBOL(__get_user_8) |
96477b4c | 106 | |
1da177e4 LT |
107 | |
108 | bad_get_user: | |
ef8c1a2d | 109 | xor %edx,%edx |
40faf463 | 110 | mov $(-EFAULT),%_ASM_AX |
63bcff2a | 111 | ASM_CLAC |
1da177e4 | 112 | ret |
8d379dad | 113 | END(bad_get_user) |
1da177e4 | 114 | |
96477b4c VS |
115 | #ifdef CONFIG_X86_32 |
116 | bad_get_user_8: | |
96477b4c VS |
117 | xor %edx,%edx |
118 | xor %ecx,%ecx | |
119 | mov $(-EFAULT),%_ASM_AX | |
120 | ASM_CLAC | |
121 | ret | |
96477b4c VS |
122 | END(bad_get_user_8) |
123 | #endif | |
124 | ||
1a27bc0d PA |
125 | _ASM_EXTABLE(1b,bad_get_user) |
126 | _ASM_EXTABLE(2b,bad_get_user) | |
127 | _ASM_EXTABLE(3b,bad_get_user) | |
6c2d4586 | 128 | #ifdef CONFIG_X86_64 |
1a27bc0d | 129 | _ASM_EXTABLE(4b,bad_get_user) |
96477b4c VS |
130 | #else |
131 | _ASM_EXTABLE(4b,bad_get_user_8) | |
132 | _ASM_EXTABLE(5b,bad_get_user_8) | |
6c2d4586 | 133 | #endif |