mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 14:14:24 +08:00
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 <bcrl@kvack.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
1886297ce0
commit
b2f680380d
@ -333,7 +333,26 @@ do { \
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
#define __get_user_asm_u64(x, ptr, retval, errret) (x) = __get_user_bad()
|
#define __get_user_asm_u64(x, ptr, retval, errret) \
|
||||||
|
({ \
|
||||||
|
__typeof__(ptr) __ptr = (ptr); \
|
||||||
|
asm volatile(ASM_STAC "\n" \
|
||||||
|
"1: movl %2,%%eax\n" \
|
||||||
|
"2: movl %3,%%edx\n" \
|
||||||
|
"3: " ASM_CLAC "\n" \
|
||||||
|
".section .fixup,\"ax\"\n" \
|
||||||
|
"4: mov %4,%0\n" \
|
||||||
|
" xorl %%eax,%%eax\n" \
|
||||||
|
" xorl %%edx,%%edx\n" \
|
||||||
|
" jmp 3b\n" \
|
||||||
|
".previous\n" \
|
||||||
|
_ASM_EXTABLE(1b, 4b) \
|
||||||
|
_ASM_EXTABLE(2b, 4b) \
|
||||||
|
: "=r" (retval), "=A"(x) \
|
||||||
|
: "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1), \
|
||||||
|
"i" (errret), "0" (retval)); \
|
||||||
|
})
|
||||||
|
|
||||||
#define __get_user_asm_ex_u64(x, ptr) (x) = __get_user_bad()
|
#define __get_user_asm_ex_u64(x, ptr) (x) = __get_user_bad()
|
||||||
#else
|
#else
|
||||||
#define __get_user_asm_u64(x, ptr, retval, errret) \
|
#define __get_user_asm_u64(x, ptr, retval, errret) \
|
||||||
@ -420,7 +439,7 @@ do { \
|
|||||||
#define __get_user_nocheck(x, ptr, size) \
|
#define __get_user_nocheck(x, ptr, size) \
|
||||||
({ \
|
({ \
|
||||||
int __gu_err; \
|
int __gu_err; \
|
||||||
unsigned long __gu_val; \
|
__inttype(*(ptr)) __gu_val; \
|
||||||
__uaccess_begin(); \
|
__uaccess_begin(); \
|
||||||
__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
|
__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
|
||||||
__uaccess_end(); \
|
__uaccess_end(); \
|
||||||
|
Loading…
Reference in New Issue
Block a user