aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/uaccess.h57
1 files changed, 14 insertions, 43 deletions
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index a8d12653f304..d710a2555fd6 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -125,13 +125,12 @@ extern int __get_user_4(void);
125extern int __get_user_8(void); 125extern int __get_user_8(void);
126extern int __get_user_bad(void); 126extern int __get_user_bad(void);
127 127
128#define __get_user_x(size, ret, x, ptr) \ 128/*
129 asm volatile("call __get_user_" #size \ 129 * This is a type: either unsigned long, if the argument fits into
130 : "=a" (ret), "=d" (x) \ 130 * that type, or otherwise unsigned long long.
131 : "0" (ptr)) \ 131 */
132 132#define __inttype(x) \
133/* Careful: we have to cast the result to the type of the pointer 133__typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
134 * for sign reasons */
135 134
136/** 135/**
137 * get_user: - Get a simple variable from user space. 136 * get_user: - Get a simple variable from user space.
@@ -149,48 +148,20 @@ extern int __get_user_bad(void);
149 * 148 *
150 * Returns zero on success, or -EFAULT on error. 149 * Returns zero on success, or -EFAULT on error.
151 * On error, the variable @x is set to zero. 150 * On error, the variable @x is set to zero.
151 *
152 * Careful: we have to cast the result to the type of the pointer
153 * for sign reasons.
152 */ 154 */
153#ifdef CONFIG_X86_32
154#define __get_user_8(ret, x, ptr) \
155do { \
156 register unsigned long long __xx asm("%edx"); \
157 asm volatile("call __get_user_8" \
158 : "=a" (ret), "=r" (__xx) \
159 : "0" (ptr)); \
160 (x) = __xx; \
161} while (0)
162
163#else
164#define __get_user_8(__ret_gu, __val_gu, ptr) \
165 __get_user_x(8, __ret_gu, __val_gu, ptr)
166#endif
167
168#define get_user(x, ptr) \ 155#define get_user(x, ptr) \
169({ \ 156({ \
170 int __ret_gu; \ 157 int __ret_gu; \
171 struct { \ 158 register __inttype(*(ptr)) __val_gu asm("%edx"); \
172 unsigned long long __val_n : 8*sizeof(*(ptr)); \
173 } __val_gu; \
174 __chk_user_ptr(ptr); \ 159 __chk_user_ptr(ptr); \
175 might_fault(); \ 160 might_fault(); \
176 switch (sizeof(*(ptr))) { \ 161 asm volatile("call __get_user_%P3" \
177 case 1: \ 162 : "=a" (__ret_gu), "=r" (__val_gu) \
178 __get_user_x(1, __ret_gu, __val_gu.__val_n, ptr); \ 163 : "0" (ptr), "i" (sizeof(*(ptr)))); \
179 break; \ 164 (x) = (__typeof__(*(ptr))) __val_gu; \
180 case 2: \
181 __get_user_x(2, __ret_gu, __val_gu.__val_n, ptr); \
182 break; \
183 case 4: \
184 __get_user_x(4, __ret_gu, __val_gu.__val_n, ptr); \
185 break; \
186 case 8: \
187 __get_user_8(__ret_gu, __val_gu.__val_n, ptr); \
188 break; \
189 default: \
190 __get_user_x(X, __ret_gu, __val_gu.__val_n, ptr); \
191 break; \
192 } \
193 (x) = (__typeof__(*(ptr)))__val_gu.__val_n; \
194 __ret_gu; \ 165 __ret_gu; \
195}) 166})
196 167