Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * __get_user functions. | |
3 | * | |
4 | * (C) Copyright 1998 Linus Torvalds | |
5 | * (C) Copyright 2005 Andi Kleen | |
6c2d4586 | 6 | * (C) Copyright 2008 Glauber Costa |
1da177e4 LT |
7 | * |
8 | * These functions have a non-standard call interface | |
9 | * to make them more efficient, especially as they | |
10 | * return an error value in addition to the "real" | |
11 | * return value. | |
12 | */ | |
13 | ||
14 | /* | |
15 | * __get_user_X | |
16 | * | |
6c2d4586 | 17 | * Inputs: %[r|e]ax contains the address. |
1da177e4 | 18 | * |
6c2d4586 GC |
19 | * Outputs: %[r|e]ax is error code (0 or -EFAULT) |
20 | * %[r|e]dx contains zero-extended value | |
96477b4c | 21 | * %ecx contains the high half for 32-bit __get_user_8 |
6c2d4586 | 22 | * |
1da177e4 LT |
23 | * |
24 | * These functions should not modify any other registers, | |
25 | * as they get called from within inline assembly. | |
26 | */ | |
27 | ||
28 | #include <linux/linkage.h> | |
8d379dad | 29 | #include <asm/dwarf2.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> |
1da177e4 LT |
36 | |
37 | .text | |
8d379dad JB |
38 | ENTRY(__get_user_1) |
39 | CFI_STARTPROC | |
40faf463 GC |
40 | GET_THREAD_INFO(%_ASM_DX) |
41 | cmp TI_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 JB |
48 | CFI_ENDPROC |
49 | ENDPROC(__get_user_1) | |
1da177e4 | 50 | |
8d379dad JB |
51 | ENTRY(__get_user_2) |
52 | CFI_STARTPROC | |
40faf463 | 53 | add $1,%_ASM_AX |
92628753 | 54 | jc bad_get_user |
40faf463 GC |
55 | GET_THREAD_INFO(%_ASM_DX) |
56 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | |
92628753 | 57 | jae bad_get_user |
63bcff2a | 58 | ASM_STAC |
40faf463 | 59 | 2: movzwl -1(%_ASM_AX),%edx |
ef8c1a2d | 60 | xor %eax,%eax |
63bcff2a | 61 | ASM_CLAC |
1da177e4 | 62 | ret |
8d379dad JB |
63 | CFI_ENDPROC |
64 | ENDPROC(__get_user_2) | |
1da177e4 | 65 | |
8d379dad JB |
66 | ENTRY(__get_user_4) |
67 | CFI_STARTPROC | |
40faf463 | 68 | add $3,%_ASM_AX |
92628753 | 69 | jc bad_get_user |
40faf463 GC |
70 | GET_THREAD_INFO(%_ASM_DX) |
71 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | |
92628753 | 72 | jae bad_get_user |
63bcff2a | 73 | ASM_STAC |
16640165 | 74 | 3: movl -3(%_ASM_AX),%edx |
ef8c1a2d | 75 | xor %eax,%eax |
63bcff2a | 76 | ASM_CLAC |
1da177e4 | 77 | ret |
8d379dad JB |
78 | CFI_ENDPROC |
79 | ENDPROC(__get_user_4) | |
1da177e4 | 80 | |
8d379dad JB |
81 | ENTRY(__get_user_8) |
82 | CFI_STARTPROC | |
96477b4c | 83 | #ifdef CONFIG_X86_64 |
40faf463 | 84 | add $7,%_ASM_AX |
92628753 | 85 | jc bad_get_user |
40faf463 GC |
86 | GET_THREAD_INFO(%_ASM_DX) |
87 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | |
96477b4c | 88 | jae bad_get_user |
63bcff2a | 89 | ASM_STAC |
16640165 | 90 | 4: movq -7(%_ASM_AX),%rdx |
ef8c1a2d | 91 | xor %eax,%eax |
63bcff2a | 92 | ASM_CLAC |
1da177e4 | 93 | ret |
96477b4c VS |
94 | #else |
95 | add $7,%_ASM_AX | |
96 | jc bad_get_user_8 | |
97 | GET_THREAD_INFO(%_ASM_DX) | |
98 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | |
99 | jae bad_get_user_8 | |
100 | ASM_STAC | |
16640165 PA |
101 | 4: movl -7(%_ASM_AX),%edx |
102 | 5: movl -3(%_ASM_AX),%ecx | |
96477b4c VS |
103 | xor %eax,%eax |
104 | ASM_CLAC | |
105 | ret | |
106 | #endif | |
8d379dad JB |
107 | CFI_ENDPROC |
108 | ENDPROC(__get_user_8) | |
96477b4c | 109 | |
1da177e4 LT |
110 | |
111 | bad_get_user: | |
8d379dad | 112 | CFI_STARTPROC |
ef8c1a2d | 113 | xor %edx,%edx |
40faf463 | 114 | mov $(-EFAULT),%_ASM_AX |
63bcff2a | 115 | ASM_CLAC |
1da177e4 | 116 | ret |
8d379dad JB |
117 | CFI_ENDPROC |
118 | END(bad_get_user) | |
1da177e4 | 119 | |
96477b4c VS |
120 | #ifdef CONFIG_X86_32 |
121 | bad_get_user_8: | |
122 | CFI_STARTPROC | |
123 | xor %edx,%edx | |
124 | xor %ecx,%ecx | |
125 | mov $(-EFAULT),%_ASM_AX | |
126 | ASM_CLAC | |
127 | ret | |
128 | CFI_ENDPROC | |
129 | END(bad_get_user_8) | |
130 | #endif | |
131 | ||
1a27bc0d PA |
132 | _ASM_EXTABLE(1b,bad_get_user) |
133 | _ASM_EXTABLE(2b,bad_get_user) | |
134 | _ASM_EXTABLE(3b,bad_get_user) | |
6c2d4586 | 135 | #ifdef CONFIG_X86_64 |
1a27bc0d | 136 | _ASM_EXTABLE(4b,bad_get_user) |
96477b4c VS |
137 | #else |
138 | _ASM_EXTABLE(4b,bad_get_user_8) | |
139 | _ASM_EXTABLE(5b,bad_get_user_8) | |
6c2d4586 | 140 | #endif |