mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-28 20:37:27 +00:00
Merge branch 'parisc-4.11-5' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc fix from Helge Deller: "One patch which fixes get_user() for 64-bit values on 32-bit kernels. Up to now we lost the upper 32-bits of the returned 64-bit value" * 'parisc-4.11-5' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: parisc: Fix get_user() for 64-bit value on 32-bit kernel
This commit is contained in:
commit
20bb78f6b3
@ -39,10 +39,10 @@
|
||||
#define get_user __get_user
|
||||
|
||||
#if !defined(CONFIG_64BIT)
|
||||
#define LDD_USER(ptr) __get_user_asm64(ptr)
|
||||
#define LDD_USER(val, ptr) __get_user_asm64(val, ptr)
|
||||
#define STD_USER(x, ptr) __put_user_asm64(x, ptr)
|
||||
#else
|
||||
#define LDD_USER(ptr) __get_user_asm("ldd", ptr)
|
||||
#define LDD_USER(val, ptr) __get_user_asm(val, "ldd", ptr)
|
||||
#define STD_USER(x, ptr) __put_user_asm("std", x, ptr)
|
||||
#endif
|
||||
|
||||
@ -97,63 +97,87 @@ struct exception_data {
|
||||
" mtsp %0,%%sr2\n\t" \
|
||||
: : "r"(get_fs()) : )
|
||||
|
||||
#define __get_user(x, ptr) \
|
||||
({ \
|
||||
register long __gu_err __asm__ ("r8") = 0; \
|
||||
register long __gu_val; \
|
||||
\
|
||||
load_sr2(); \
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __get_user_asm("ldb", ptr); break; \
|
||||
case 2: __get_user_asm("ldh", ptr); break; \
|
||||
case 4: __get_user_asm("ldw", ptr); break; \
|
||||
case 8: LDD_USER(ptr); break; \
|
||||
default: BUILD_BUG(); break; \
|
||||
} \
|
||||
\
|
||||
(x) = (__force __typeof__(*(ptr))) __gu_val; \
|
||||
__gu_err; \
|
||||
#define __get_user_internal(val, ptr) \
|
||||
({ \
|
||||
register long __gu_err __asm__ ("r8") = 0; \
|
||||
\
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __get_user_asm(val, "ldb", ptr); break; \
|
||||
case 2: __get_user_asm(val, "ldh", ptr); break; \
|
||||
case 4: __get_user_asm(val, "ldw", ptr); break; \
|
||||
case 8: LDD_USER(val, ptr); break; \
|
||||
default: BUILD_BUG(); \
|
||||
} \
|
||||
\
|
||||
__gu_err; \
|
||||
})
|
||||
|
||||
#define __get_user_asm(ldx, ptr) \
|
||||
#define __get_user(val, ptr) \
|
||||
({ \
|
||||
load_sr2(); \
|
||||
__get_user_internal(val, ptr); \
|
||||
})
|
||||
|
||||
#define __get_user_asm(val, ldx, ptr) \
|
||||
{ \
|
||||
register long __gu_val; \
|
||||
\
|
||||
__asm__("1: " ldx " 0(%%sr2,%2),%0\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
: "=r"(__gu_val), "=r"(__gu_err) \
|
||||
: "r"(ptr), "1"(__gu_err));
|
||||
: "r"(ptr), "1"(__gu_err)); \
|
||||
\
|
||||
(val) = (__force __typeof__(*(ptr))) __gu_val; \
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_64BIT)
|
||||
|
||||
#define __get_user_asm64(ptr) \
|
||||
#define __get_user_asm64(val, ptr) \
|
||||
{ \
|
||||
union { \
|
||||
unsigned long long l; \
|
||||
__typeof__(*(ptr)) t; \
|
||||
} __gu_tmp; \
|
||||
\
|
||||
__asm__(" copy %%r0,%R0\n" \
|
||||
"1: ldw 0(%%sr2,%2),%0\n" \
|
||||
"2: ldw 4(%%sr2,%2),%R0\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
|
||||
: "=r"(__gu_val), "=r"(__gu_err) \
|
||||
: "r"(ptr), "1"(__gu_err));
|
||||
: "=&r"(__gu_tmp.l), "=r"(__gu_err) \
|
||||
: "r"(ptr), "1"(__gu_err)); \
|
||||
\
|
||||
(val) = __gu_tmp.t; \
|
||||
}
|
||||
|
||||
#endif /* !defined(CONFIG_64BIT) */
|
||||
|
||||
|
||||
#define __put_user(x, ptr) \
|
||||
#define __put_user_internal(x, ptr) \
|
||||
({ \
|
||||
register long __pu_err __asm__ ("r8") = 0; \
|
||||
__typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \
|
||||
\
|
||||
load_sr2(); \
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __put_user_asm("stb", __x, ptr); break; \
|
||||
case 2: __put_user_asm("sth", __x, ptr); break; \
|
||||
case 4: __put_user_asm("stw", __x, ptr); break; \
|
||||
case 8: STD_USER(__x, ptr); break; \
|
||||
default: BUILD_BUG(); break; \
|
||||
} \
|
||||
case 1: __put_user_asm("stb", __x, ptr); break; \
|
||||
case 2: __put_user_asm("sth", __x, ptr); break; \
|
||||
case 4: __put_user_asm("stw", __x, ptr); break; \
|
||||
case 8: STD_USER(__x, ptr); break; \
|
||||
default: BUILD_BUG(); \
|
||||
} \
|
||||
\
|
||||
__pu_err; \
|
||||
})
|
||||
|
||||
#define __put_user(x, ptr) \
|
||||
({ \
|
||||
load_sr2(); \
|
||||
__put_user_internal(x, ptr); \
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
* The "__put_user/kernel_asm()" macros tell gcc they read from memory
|
||||
* instead of writing. This is because they do not write to any memory
|
||||
|
Loading…
Reference in New Issue
Block a user