]>
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> | |
0341c14d | 29 | #include <asm/page_types.h> |
1da177e4 | 30 | #include <asm/errno.h> |
e2d5df93 | 31 | #include <asm/asm-offsets.h> |
1da177e4 | 32 | #include <asm/thread_info.h> |
40faf463 | 33 | #include <asm/asm.h> |
63bcff2a | 34 | #include <asm/smap.h> |
1da177e4 LT |
35 | |
36 | .text | |
8d379dad | 37 | ENTRY(__get_user_1) |
40faf463 GC |
38 | GET_THREAD_INFO(%_ASM_DX) |
39 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | |
1da177e4 | 40 | jae bad_get_user |
63bcff2a | 41 | ASM_STAC |
16640165 | 42 | 1: movzbl (%_ASM_AX),%edx |
ef8c1a2d | 43 | xor %eax,%eax |
63bcff2a | 44 | ASM_CLAC |
1da177e4 | 45 | ret |
8d379dad | 46 | ENDPROC(__get_user_1) |
1da177e4 | 47 | |
8d379dad | 48 | ENTRY(__get_user_2) |
40faf463 | 49 | add $1,%_ASM_AX |
92628753 | 50 | jc bad_get_user |
40faf463 GC |
51 | GET_THREAD_INFO(%_ASM_DX) |
52 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | |
92628753 | 53 | jae bad_get_user |
63bcff2a | 54 | ASM_STAC |
40faf463 | 55 | 2: movzwl -1(%_ASM_AX),%edx |
ef8c1a2d | 56 | xor %eax,%eax |
63bcff2a | 57 | ASM_CLAC |
1da177e4 | 58 | ret |
8d379dad | 59 | ENDPROC(__get_user_2) |
1da177e4 | 60 | |
8d379dad | 61 | ENTRY(__get_user_4) |
40faf463 | 62 | add $3,%_ASM_AX |
92628753 | 63 | jc bad_get_user |
40faf463 GC |
64 | GET_THREAD_INFO(%_ASM_DX) |
65 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | |
92628753 | 66 | jae bad_get_user |
63bcff2a | 67 | ASM_STAC |
16640165 | 68 | 3: movl -3(%_ASM_AX),%edx |
ef8c1a2d | 69 | xor %eax,%eax |
63bcff2a | 70 | ASM_CLAC |
1da177e4 | 71 | ret |
8d379dad | 72 | ENDPROC(__get_user_4) |
1da177e4 | 73 | |
8d379dad | 74 | ENTRY(__get_user_8) |
96477b4c | 75 | #ifdef CONFIG_X86_64 |
40faf463 | 76 | add $7,%_ASM_AX |
92628753 | 77 | jc bad_get_user |
40faf463 GC |
78 | GET_THREAD_INFO(%_ASM_DX) |
79 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | |
96477b4c | 80 | jae bad_get_user |
63bcff2a | 81 | ASM_STAC |
16640165 | 82 | 4: movq -7(%_ASM_AX),%rdx |
ef8c1a2d | 83 | xor %eax,%eax |
63bcff2a | 84 | ASM_CLAC |
1da177e4 | 85 | ret |
96477b4c VS |
86 | #else |
87 | add $7,%_ASM_AX | |
88 | jc bad_get_user_8 | |
89 | GET_THREAD_INFO(%_ASM_DX) | |
90 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | |
91 | jae bad_get_user_8 | |
92 | ASM_STAC | |
16640165 PA |
93 | 4: movl -7(%_ASM_AX),%edx |
94 | 5: movl -3(%_ASM_AX),%ecx | |
96477b4c VS |
95 | xor %eax,%eax |
96 | ASM_CLAC | |
97 | ret | |
98 | #endif | |
8d379dad | 99 | ENDPROC(__get_user_8) |
96477b4c | 100 | |
1da177e4 LT |
101 | |
102 | bad_get_user: | |
ef8c1a2d | 103 | xor %edx,%edx |
40faf463 | 104 | mov $(-EFAULT),%_ASM_AX |
63bcff2a | 105 | ASM_CLAC |
1da177e4 | 106 | ret |
8d379dad | 107 | END(bad_get_user) |
1da177e4 | 108 | |
96477b4c VS |
109 | #ifdef CONFIG_X86_32 |
110 | bad_get_user_8: | |
96477b4c VS |
111 | xor %edx,%edx |
112 | xor %ecx,%ecx | |
113 | mov $(-EFAULT),%_ASM_AX | |
114 | ASM_CLAC | |
115 | ret | |
96477b4c VS |
116 | END(bad_get_user_8) |
117 | #endif | |
118 | ||
1a27bc0d PA |
119 | _ASM_EXTABLE(1b,bad_get_user) |
120 | _ASM_EXTABLE(2b,bad_get_user) | |
121 | _ASM_EXTABLE(3b,bad_get_user) | |
6c2d4586 | 122 | #ifdef CONFIG_X86_64 |
1a27bc0d | 123 | _ASM_EXTABLE(4b,bad_get_user) |
96477b4c VS |
124 | #else |
125 | _ASM_EXTABLE(4b,bad_get_user_8) | |
126 | _ASM_EXTABLE(5b,bad_get_user_8) | |
6c2d4586 | 127 | #endif |