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