Skip to content

Commit b2f6803

Browse files
bcrlIngo Molnar
authored andcommitted
x86/mm/32: Add support for 64-bit __get_user() on 32-bit kernels
The existing __get_user() implementation does not support fetching 64-bit values on 32-bit x86. Implement this in a way that does not generate any incorrect warnings as cautioned by Russell King. Test code available at: http://www.kvack.org/~bcrl/x86_32-get_user.tar . Signed-off-by: Benjamin LaHaise <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: [email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 1886297 commit b2f6803

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

arch/x86/include/asm/uaccess.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,26 @@ do { \
333333
} while (0)
334334

335335
#ifdef CONFIG_X86_32
336-
#define __get_user_asm_u64(x, ptr, retval, errret) (x) = __get_user_bad()
336+
#define __get_user_asm_u64(x, ptr, retval, errret) \
337+
({ \
338+
__typeof__(ptr) __ptr = (ptr); \
339+
asm volatile(ASM_STAC "\n" \
340+
"1: movl %2,%%eax\n" \
341+
"2: movl %3,%%edx\n" \
342+
"3: " ASM_CLAC "\n" \
343+
".section .fixup,\"ax\"\n" \
344+
"4: mov %4,%0\n" \
345+
" xorl %%eax,%%eax\n" \
346+
" xorl %%edx,%%edx\n" \
347+
" jmp 3b\n" \
348+
".previous\n" \
349+
_ASM_EXTABLE(1b, 4b) \
350+
_ASM_EXTABLE(2b, 4b) \
351+
: "=r" (retval), "=A"(x) \
352+
: "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1), \
353+
"i" (errret), "0" (retval)); \
354+
})
355+
337356
#define __get_user_asm_ex_u64(x, ptr) (x) = __get_user_bad()
338357
#else
339358
#define __get_user_asm_u64(x, ptr, retval, errret) \
@@ -420,7 +439,7 @@ do { \
420439
#define __get_user_nocheck(x, ptr, size) \
421440
({ \
422441
int __gu_err; \
423-
unsigned long __gu_val; \
442+
__inttype(*(ptr)) __gu_val; \
424443
__uaccess_begin(); \
425444
__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
426445
__uaccess_end(); \

0 commit comments

Comments
 (0)