]>
Commit | Line | Data |
---|---|---|
19e2e172 | 1 | /* |
c0ff3c53 RB |
2 | * Access to user system call parameters and results |
3 | * | |
19e2e172 RB |
4 | * This file is subject to the terms and conditions of the GNU General Public |
5 | * License. See the file "COPYING" in the main directory of this archive | |
6 | * for more details. | |
7 | * | |
c0ff3c53 RB |
8 | * See asm-generic/syscall.h for descriptions of what we must do here. |
9 | * | |
19e2e172 RB |
10 | * Copyright (C) 2012 Ralf Baechle <ralf@linux-mips.org> |
11 | */ | |
12 | ||
13 | #ifndef __ASM_MIPS_SYSCALL_H | |
14 | #define __ASM_MIPS_SYSCALL_H | |
15 | ||
f5179287 | 16 | #include <linux/compiler.h> |
bec9b2b2 RB |
17 | #include <linux/audit.h> |
18 | #include <linux/elf-em.h> | |
c0ff3c53 RB |
19 | #include <linux/kernel.h> |
20 | #include <linux/sched.h> | |
21 | #include <linux/uaccess.h> | |
22 | #include <asm/ptrace.h> | |
23 | ||
24 | static inline long syscall_get_nr(struct task_struct *task, | |
25 | struct pt_regs *regs) | |
26 | { | |
27 | return regs->regs[2]; | |
28 | } | |
29 | ||
30 | static inline unsigned long mips_get_syscall_arg(unsigned long *arg, | |
31 | struct task_struct *task, struct pt_regs *regs, unsigned int n) | |
32 | { | |
63238f2c | 33 | unsigned long usp __maybe_unused = regs->regs[29]; |
c0ff3c53 RB |
34 | |
35 | switch (n) { | |
36 | case 0: case 1: case 2: case 3: | |
37 | *arg = regs->regs[4 + n]; | |
38 | ||
39 | return 0; | |
40 | ||
41 | #ifdef CONFIG_32BIT | |
42 | case 4: case 5: case 6: case 7: | |
86ca57b5 | 43 | return get_user(*arg, (int *)usp + n); |
c0ff3c53 RB |
44 | #endif |
45 | ||
46 | #ifdef CONFIG_64BIT | |
47 | case 4: case 5: case 6: case 7: | |
48 | #ifdef CONFIG_MIPS32_O32 | |
49 | if (test_thread_flag(TIF_32BIT_REGS)) | |
86ca57b5 | 50 | return get_user(*arg, (int *)usp + n); |
c0ff3c53 RB |
51 | else |
52 | #endif | |
53 | *arg = regs->regs[4 + n]; | |
54 | ||
55 | return 0; | |
56 | #endif | |
57 | ||
58 | default: | |
59 | BUG(); | |
60 | } | |
f5179287 RB |
61 | |
62 | unreachable(); | |
c0ff3c53 RB |
63 | } |
64 | ||
1d7bf993 RB |
65 | static inline long syscall_get_return_value(struct task_struct *task, |
66 | struct pt_regs *regs) | |
67 | { | |
68 | return regs->regs[2]; | |
69 | } | |
70 | ||
71 | static inline void syscall_set_return_value(struct task_struct *task, | |
72 | struct pt_regs *regs, | |
73 | int error, long val) | |
74 | { | |
75 | if (error) { | |
76 | regs->regs[2] = -error; | |
77 | regs->regs[7] = -1; | |
78 | } else { | |
79 | regs->regs[2] = val; | |
80 | regs->regs[7] = 0; | |
81 | } | |
82 | } | |
83 | ||
c0ff3c53 RB |
84 | static inline void syscall_get_arguments(struct task_struct *task, |
85 | struct pt_regs *regs, | |
86 | unsigned int i, unsigned int n, | |
87 | unsigned long *args) | |
88 | { | |
c0ff3c53 RB |
89 | int ret; |
90 | ||
91 | while (n--) | |
a8031d2c | 92 | ret |= mips_get_syscall_arg(args++, task, regs, i++); |
c0ff3c53 RB |
93 | |
94 | /* | |
95 | * No way to communicate an error because this is a void function. | |
96 | */ | |
97 | #if 0 | |
98 | return ret; | |
99 | #endif | |
100 | } | |
101 | ||
19e2e172 RB |
102 | extern const unsigned long sys_call_table[]; |
103 | extern const unsigned long sys32_call_table[]; | |
104 | extern const unsigned long sysn32_call_table[]; | |
105 | ||
bec9b2b2 RB |
106 | static inline int __syscall_get_arch(void) |
107 | { | |
108 | int arch = EM_MIPS; | |
109 | #ifdef CONFIG_64BIT | |
110 | arch |= __AUDIT_ARCH_64BIT; | |
111 | #endif | |
112 | #if defined(__LITTLE_ENDIAN) | |
113 | arch |= __AUDIT_ARCH_LE; | |
114 | #endif | |
115 | return arch; | |
116 | } | |
117 | ||
19e2e172 | 118 | #endif /* __ASM_MIPS_SYSCALL_H */ |