diff options
Diffstat (limited to 'arch/x86/lib/getuser.S')
-rw-r--r-- | arch/x86/lib/getuser.S | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S index 156b9c804670..d3bf9f99ca77 100644 --- a/arch/x86/lib/getuser.S +++ b/arch/x86/lib/getuser.S | |||
@@ -15,11 +15,10 @@ | |||
15 | * __get_user_X | 15 | * __get_user_X |
16 | * | 16 | * |
17 | * Inputs: %[r|e]ax contains the address. | 17 | * Inputs: %[r|e]ax contains the address. |
18 | * The register is modified, but all changes are undone | ||
19 | * before returning because the C code doesn't know about it. | ||
20 | * | 18 | * |
21 | * Outputs: %[r|e]ax is error code (0 or -EFAULT) | 19 | * Outputs: %[r|e]ax is error code (0 or -EFAULT) |
22 | * %[r|e]dx contains zero-extended value | 20 | * %[r|e]dx contains zero-extended value |
21 | * %ecx contains the high half for 32-bit __get_user_8 | ||
23 | * | 22 | * |
24 | * | 23 | * |
25 | * These functions should not modify any other registers, | 24 | * These functions should not modify any other registers, |
@@ -79,22 +78,35 @@ ENTRY(__get_user_4) | |||
79 | CFI_ENDPROC | 78 | CFI_ENDPROC |
80 | ENDPROC(__get_user_4) | 79 | ENDPROC(__get_user_4) |
81 | 80 | ||
82 | #ifdef CONFIG_X86_64 | ||
83 | ENTRY(__get_user_8) | 81 | ENTRY(__get_user_8) |
84 | CFI_STARTPROC | 82 | CFI_STARTPROC |
83 | #ifdef CONFIG_X86_64 | ||
85 | add $7,%_ASM_AX | 84 | add $7,%_ASM_AX |
86 | jc bad_get_user | 85 | jc bad_get_user |
87 | GET_THREAD_INFO(%_ASM_DX) | 86 | GET_THREAD_INFO(%_ASM_DX) |
88 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX | 87 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX |
89 | jae bad_get_user | 88 | jae bad_get_user |
90 | ASM_STAC | 89 | ASM_STAC |
91 | 4: movq -7(%_ASM_AX),%_ASM_DX | 90 | 4: movq -7(%_ASM_AX),%_ASM_DX |
92 | xor %eax,%eax | 91 | xor %eax,%eax |
93 | ASM_CLAC | 92 | ASM_CLAC |
94 | ret | 93 | ret |
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 | ||
101 | 4: mov -7(%_ASM_AX),%edx | ||
102 | 5: mov -3(%_ASM_AX),%ecx | ||
103 | xor %eax,%eax | ||
104 | ASM_CLAC | ||
105 | ret | ||
106 | #endif | ||
95 | CFI_ENDPROC | 107 | CFI_ENDPROC |
96 | ENDPROC(__get_user_8) | 108 | ENDPROC(__get_user_8) |
97 | #endif | 109 | |
98 | 110 | ||
99 | bad_get_user: | 111 | bad_get_user: |
100 | CFI_STARTPROC | 112 | CFI_STARTPROC |
@@ -105,9 +117,24 @@ bad_get_user: | |||
105 | CFI_ENDPROC | 117 | CFI_ENDPROC |
106 | END(bad_get_user) | 118 | END(bad_get_user) |
107 | 119 | ||
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 | |||
108 | _ASM_EXTABLE(1b,bad_get_user) | 132 | _ASM_EXTABLE(1b,bad_get_user) |
109 | _ASM_EXTABLE(2b,bad_get_user) | 133 | _ASM_EXTABLE(2b,bad_get_user) |
110 | _ASM_EXTABLE(3b,bad_get_user) | 134 | _ASM_EXTABLE(3b,bad_get_user) |
111 | #ifdef CONFIG_X86_64 | 135 | #ifdef CONFIG_X86_64 |
112 | _ASM_EXTABLE(4b,bad_get_user) | 136 | _ASM_EXTABLE(4b,bad_get_user) |
137 | #else | ||
138 | _ASM_EXTABLE(4b,bad_get_user_8) | ||
139 | _ASM_EXTABLE(5b,bad_get_user_8) | ||
113 | #endif | 140 | #endif |