Skip to content

Commit

Permalink
x86: get rid of 'rtype' argument to __get_user_asm() macro
Browse files Browse the repository at this point in the history
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 <torvalds@linux-foundation.org>
  • Loading branch information
Linus Torvalds committed Apr 1, 2020
1 parent 3680785 commit 7da63b3
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions arch/x86/include/asm/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,17 @@ extern int __get_user_bad(void);
})

/*
* This is a type: either unsigned long, if the argument fits into
* that type, or otherwise unsigned long long.
* This is the smallest unsigned integer type that can fit a value
* (up to 'long long')
*/
#define __inttype(x) \
__typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
#define __inttype(x) __typeof__( \
__typefits(x,char, \
__typefits(x,short, \
__typefits(x,int, \
__typefits(x,long,0ULL)))))

#define __typefits(x,type,not) \
__builtin_choose_expr(sizeof(x)<=sizeof(type),(unsigned type)0,not)

/**
* get_user - Get a simple variable from user space.
Expand Down Expand Up @@ -301,7 +307,7 @@ do { \

#else
#define __get_user_asm_u64(x, ptr, retval) \
__get_user_asm(x, ptr, retval, "q", "", "=r")
__get_user_asm(x, ptr, retval, "q", "=r")
#endif

#define __get_user_size(x, ptr, size, retval) \
Expand All @@ -310,13 +316,13 @@ do { \
__chk_user_ptr(ptr); \
switch (size) { \
case 1: \
__get_user_asm(x, ptr, retval, "b", "b", "=q"); \
__get_user_asm(x, ptr, retval, "b", "=q"); \
break; \
case 2: \
__get_user_asm(x, ptr, retval, "w", "w", "=r"); \
__get_user_asm(x, ptr, retval, "w", "=r"); \
break; \
case 4: \
__get_user_asm(x, ptr, retval, "l", "k", "=r"); \
__get_user_asm(x, ptr, retval, "l", "=r"); \
break; \
case 8: \
__get_user_asm_u64(x, ptr, retval); \
Expand All @@ -326,13 +332,13 @@ do { \
} \
} while (0)

#define __get_user_asm(x, addr, err, itype, rtype, ltype) \
#define __get_user_asm(x, addr, err, itype, ltype) \
asm volatile("\n" \
"1: mov"itype" %2,%"rtype"1\n" \
"1: mov"itype" %2,%1\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: mov %3,%0\n" \
" xor"itype" %"rtype"1,%"rtype"1\n" \
" xor"itype" %1,%1\n" \
" jmp 2b\n" \
".previous\n" \
_ASM_EXTABLE_UA(1b, 3b) \
Expand Down

0 comments on commit 7da63b3

Please sign in to comment.