Skip to content

Commit 7da63b3

Browse files
committed
x86: get rid of 'rtype' argument to __get_user_asm() macro
This is the exact same thing as 3680785 ("x86: get rid of 'rtype' argument to __put_user_goto() macro") except it's about __get_user_asm() rather than __put_user_goto(). The reasons are the same: having the low-level asm access the argument with a different size than the compiler thinks it does is fundamentally wrong. But unlike the __put_user_goto() case, we actually did tell the compiler that we used a bigger variable (either long or long long), and then only filled in the low bits, and ended up "fixing" this by casting the result to the proper pointer type. That's because we needed to use a non-qualified type (the user pointer might be a const pointer!), and that makes this a bit more painful. Our '__inttype()' macro used to be lazy and only differentiate between "fits in a register" or "needs two registers". So this fix had to also make that '__inttype()' macro more precise. Signed-off-by: Linus Torvalds <[email protected]>
1 parent 3680785 commit 7da63b3

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

arch/x86/include/asm/uaccess.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,17 @@ extern int __get_user_bad(void);
126126
})
127127

128128
/*
129-
* This is a type: either unsigned long, if the argument fits into
130-
* that type, or otherwise unsigned long long.
129+
* This is the smallest unsigned integer type that can fit a value
130+
* (up to 'long long')
131131
*/
132-
#define __inttype(x) \
133-
__typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
132+
#define __inttype(x) __typeof__( \
133+
__typefits(x,char, \
134+
__typefits(x,short, \
135+
__typefits(x,int, \
136+
__typefits(x,long,0ULL)))))
137+
138+
#define __typefits(x,type,not) \
139+
__builtin_choose_expr(sizeof(x)<=sizeof(type),(unsigned type)0,not)
134140

135141
/**
136142
* get_user - Get a simple variable from user space.
@@ -301,7 +307,7 @@ do { \
301307

302308
#else
303309
#define __get_user_asm_u64(x, ptr, retval) \
304-
__get_user_asm(x, ptr, retval, "q", "", "=r")
310+
__get_user_asm(x, ptr, retval, "q", "=r")
305311
#endif
306312

307313
#define __get_user_size(x, ptr, size, retval) \
@@ -310,13 +316,13 @@ do { \
310316
__chk_user_ptr(ptr); \
311317
switch (size) { \
312318
case 1: \
313-
__get_user_asm(x, ptr, retval, "b", "b", "=q"); \
319+
__get_user_asm(x, ptr, retval, "b", "=q"); \
314320
break; \
315321
case 2: \
316-
__get_user_asm(x, ptr, retval, "w", "w", "=r"); \
322+
__get_user_asm(x, ptr, retval, "w", "=r"); \
317323
break; \
318324
case 4: \
319-
__get_user_asm(x, ptr, retval, "l", "k", "=r"); \
325+
__get_user_asm(x, ptr, retval, "l", "=r"); \
320326
break; \
321327
case 8: \
322328
__get_user_asm_u64(x, ptr, retval); \
@@ -326,13 +332,13 @@ do { \
326332
} \
327333
} while (0)
328334

329-
#define __get_user_asm(x, addr, err, itype, rtype, ltype) \
335+
#define __get_user_asm(x, addr, err, itype, ltype) \
330336
asm volatile("\n" \
331-
"1: mov"itype" %2,%"rtype"1\n" \
337+
"1: mov"itype" %2,%1\n" \
332338
"2:\n" \
333339
".section .fixup,\"ax\"\n" \
334340
"3: mov %3,%0\n" \
335-
" xor"itype" %"rtype"1,%"rtype"1\n" \
341+
" xor"itype" %1,%1\n" \
336342
" jmp 2b\n" \
337343
".previous\n" \
338344
_ASM_EXTABLE_UA(1b, 3b) \

0 commit comments

Comments
 (0)