diff options
Diffstat (limited to 'arch/mips/include/asm/syscall.h')
-rw-r--r-- | arch/mips/include/asm/syscall.h | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index f35b131977e6..17960fe7a8ce 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h | |||
@@ -14,17 +14,28 @@ | |||
14 | #define __ASM_MIPS_SYSCALL_H | 14 | #define __ASM_MIPS_SYSCALL_H |
15 | 15 | ||
16 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
17 | #include <linux/audit.h> | 17 | #include <uapi/linux/audit.h> |
18 | #include <linux/elf-em.h> | 18 | #include <linux/elf-em.h> |
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <asm/ptrace.h> | 22 | #include <asm/ptrace.h> |
23 | #include <asm/unistd.h> | ||
24 | |||
25 | #ifndef __NR_syscall /* Only defined if _MIPS_SIM == _MIPS_SIM_ABI32 */ | ||
26 | #define __NR_syscall 4000 | ||
27 | #endif | ||
23 | 28 | ||
24 | static inline long syscall_get_nr(struct task_struct *task, | 29 | static inline long syscall_get_nr(struct task_struct *task, |
25 | struct pt_regs *regs) | 30 | struct pt_regs *regs) |
26 | { | 31 | { |
27 | return regs->regs[2]; | 32 | /* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */ |
33 | if ((config_enabled(CONFIG_32BIT) || | ||
34 | test_tsk_thread_flag(task, TIF_32BIT_REGS)) && | ||
35 | (regs->regs[2] == __NR_syscall)) | ||
36 | return regs->regs[4]; | ||
37 | else | ||
38 | return regs->regs[2]; | ||
28 | } | 39 | } |
29 | 40 | ||
30 | static inline unsigned long mips_get_syscall_arg(unsigned long *arg, | 41 | static inline unsigned long mips_get_syscall_arg(unsigned long *arg, |
@@ -68,6 +79,12 @@ static inline long syscall_get_return_value(struct task_struct *task, | |||
68 | return regs->regs[2]; | 79 | return regs->regs[2]; |
69 | } | 80 | } |
70 | 81 | ||
82 | static inline void syscall_rollback(struct task_struct *task, | ||
83 | struct pt_regs *regs) | ||
84 | { | ||
85 | /* Do nothing */ | ||
86 | } | ||
87 | |||
71 | static inline void syscall_set_return_value(struct task_struct *task, | 88 | static inline void syscall_set_return_value(struct task_struct *task, |
72 | struct pt_regs *regs, | 89 | struct pt_regs *regs, |
73 | int error, long val) | 90 | int error, long val) |
@@ -87,6 +104,13 @@ static inline void syscall_get_arguments(struct task_struct *task, | |||
87 | unsigned long *args) | 104 | unsigned long *args) |
88 | { | 105 | { |
89 | int ret; | 106 | int ret; |
107 | /* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */ | ||
108 | if ((config_enabled(CONFIG_32BIT) || | ||
109 | test_tsk_thread_flag(task, TIF_32BIT_REGS)) && | ||
110 | (regs->regs[2] == __NR_syscall)) { | ||
111 | i++; | ||
112 | n++; | ||
113 | } | ||
90 | 114 | ||
91 | while (n--) | 115 | while (n--) |
92 | ret |= mips_get_syscall_arg(args++, task, regs, i++); | 116 | ret |= mips_get_syscall_arg(args++, task, regs, i++); |
@@ -103,11 +127,14 @@ extern const unsigned long sys_call_table[]; | |||
103 | extern const unsigned long sys32_call_table[]; | 127 | extern const unsigned long sys32_call_table[]; |
104 | extern const unsigned long sysn32_call_table[]; | 128 | extern const unsigned long sysn32_call_table[]; |
105 | 129 | ||
106 | static inline int __syscall_get_arch(void) | 130 | static inline int syscall_get_arch(void) |
107 | { | 131 | { |
108 | int arch = EM_MIPS; | 132 | int arch = EM_MIPS; |
109 | #ifdef CONFIG_64BIT | 133 | #ifdef CONFIG_64BIT |
110 | arch |= __AUDIT_ARCH_64BIT; | 134 | if (!test_thread_flag(TIF_32BIT_REGS)) |
135 | arch |= __AUDIT_ARCH_64BIT; | ||
136 | if (test_thread_flag(TIF_32BIT_ADDR)) | ||
137 | arch |= __AUDIT_ARCH_CONVENTION_MIPS64_N32; | ||
111 | #endif | 138 | #endif |
112 | #if defined(__LITTLE_ENDIAN) | 139 | #if defined(__LITTLE_ENDIAN) |
113 | arch |= __AUDIT_ARCH_LE; | 140 | arch |= __AUDIT_ARCH_LE; |