aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/compat.h13
-rw-r--r--arch/x86/include/asm/syscall.h5
-rw-r--r--arch/x86/include/asm/unistd.h7
-rw-r--r--arch/x86/kernel/entry_64.S10
4 files changed, 31 insertions, 4 deletions
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 30d737ef2a42..7938b84e4506 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -7,6 +7,7 @@
7#include <linux/types.h> 7#include <linux/types.h>
8#include <linux/sched.h> 8#include <linux/sched.h>
9#include <asm/user32.h> 9#include <asm/user32.h>
10#include <asm/unistd.h>
10 11
11#define COMPAT_USER_HZ 100 12#define COMPAT_USER_HZ 100
12#define COMPAT_UTS_MACHINE "i686\0\0" 13#define COMPAT_UTS_MACHINE "i686\0\0"
@@ -212,9 +213,17 @@ static inline void __user *arch_compat_alloc_user_space(long len)
212 return (void __user *)regs->sp - len; 213 return (void __user *)regs->sp - len;
213} 214}
214 215
215static inline int is_compat_task(void) 216static inline bool is_compat_task(void)
216{ 217{
217 return current_thread_info()->status & TS_COMPAT; 218#ifdef CONFIG_IA32_EMULATION
219 if (current_thread_info()->status & TS_COMPAT)
220 return true;
221#endif
222#ifdef CONFIG_X86_X32_ABI
223 if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
224 return true;
225#endif
226 return false;
218} 227}
219 228
220#endif /* _ASM_X86_COMPAT_H */ 229#endif /* _ASM_X86_COMPAT_H */
diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h
index d962e5652a73..386b78686c4d 100644
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -16,6 +16,7 @@
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <asm/asm-offsets.h> /* For NR_syscalls */ 18#include <asm/asm-offsets.h> /* For NR_syscalls */
19#include <asm/unistd.h>
19 20
20extern const unsigned long sys_call_table[]; 21extern const unsigned long sys_call_table[];
21 22
@@ -26,13 +27,13 @@ extern const unsigned long sys_call_table[];
26 */ 27 */
27static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) 28static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
28{ 29{
29 return regs->orig_ax; 30 return regs->orig_ax & __SYSCALL_MASK;
30} 31}
31 32
32static inline void syscall_rollback(struct task_struct *task, 33static inline void syscall_rollback(struct task_struct *task,
33 struct pt_regs *regs) 34 struct pt_regs *regs)
34{ 35{
35 regs->ax = regs->orig_ax; 36 regs->ax = regs->orig_ax & __SYSCALL_MASK;
36} 37}
37 38
38static inline long syscall_get_error(struct task_struct *task, 39static inline long syscall_get_error(struct task_struct *task,
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 7a48a5557470..37cdc9d99bb1 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -5,6 +5,13 @@
5#define __X32_SYSCALL_BIT 0x40000000 5#define __X32_SYSCALL_BIT 0x40000000
6 6
7#ifdef __KERNEL__ 7#ifdef __KERNEL__
8
9# ifdef CONFIG_X86_X32_ABI
10# define __SYSCALL_MASK (~(__X32_SYSCALL_BIT))
11# else
12# define __SYSCALL_MASK (~0)
13# endif
14
8# ifdef CONFIG_X86_32 15# ifdef CONFIG_X86_32
9 16
10# include <asm/unistd_32.h> 17# include <asm/unistd_32.h>
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 3fe8239fd8fb..a17b34216971 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -482,7 +482,12 @@ GLOBAL(system_call_after_swapgs)
482 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) 482 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
483 jnz tracesys 483 jnz tracesys
484system_call_fastpath: 484system_call_fastpath:
485#if __SYSCALL_MASK == ~0
485 cmpq $__NR_syscall_max,%rax 486 cmpq $__NR_syscall_max,%rax
487#else
488 andl $__SYSCALL_MASK,%eax
489 cmpl $__NR_syscall_max,%eax
490#endif
486 ja badsys 491 ja badsys
487 movq %r10,%rcx 492 movq %r10,%rcx
488 call *sys_call_table(,%rax,8) # XXX: rip relative 493 call *sys_call_table(,%rax,8) # XXX: rip relative
@@ -596,7 +601,12 @@ tracesys:
596 */ 601 */
597 LOAD_ARGS ARGOFFSET, 1 602 LOAD_ARGS ARGOFFSET, 1
598 RESTORE_REST 603 RESTORE_REST
604#if __SYSCALL_MASK == ~0
599 cmpq $__NR_syscall_max,%rax 605 cmpq $__NR_syscall_max,%rax
606#else
607 andl $__SYSCALL_MASK,%eax
608 cmpl $__NR_syscall_max,%eax
609#endif
600 ja int_ret_from_sys_call /* RAX(%rsp) set to -ENOSYS above */ 610 ja int_ret_from_sys_call /* RAX(%rsp) set to -ENOSYS above */
601 movq %r10,%rcx /* fixup for C */ 611 movq %r10,%rcx /* fixup for C */
602 call *sys_call_table(,%rax,8) 612 call *sys_call_table(,%rax,8)