.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
---|
1 | 2 | /* |
---|
2 | 3 | * Access to user system call parameters and results |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved. |
---|
5 | | - * |
---|
6 | | - * This copyrighted material is made available to anyone wishing to use, |
---|
7 | | - * modify, copy, or redistribute it subject to the terms and conditions |
---|
8 | | - * of the GNU General Public License v.2. |
---|
9 | 6 | * |
---|
10 | 7 | * See asm-generic/syscall.h for descriptions of what we must do here. |
---|
11 | 8 | */ |
---|
.. | .. |
---|
16 | 13 | #include <uapi/linux/audit.h> |
---|
17 | 14 | #include <linux/sched.h> |
---|
18 | 15 | #include <linux/err.h> |
---|
19 | | -#include <asm/asm-offsets.h> /* For NR_syscalls */ |
---|
20 | 16 | #include <asm/thread_info.h> /* for TS_COMPAT */ |
---|
21 | 17 | #include <asm/unistd.h> |
---|
22 | 18 | |
---|
23 | | -#ifdef CONFIG_X86_64 |
---|
24 | | -typedef asmlinkage long (*sys_call_ptr_t)(const struct pt_regs *); |
---|
25 | | -#else |
---|
26 | | -typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long, |
---|
27 | | - unsigned long, unsigned long, |
---|
28 | | - unsigned long, unsigned long); |
---|
29 | | -#endif /* CONFIG_X86_64 */ |
---|
| 19 | +typedef long (*sys_call_ptr_t)(const struct pt_regs *); |
---|
30 | 20 | extern const sys_call_ptr_t sys_call_table[]; |
---|
31 | 21 | |
---|
32 | 22 | #if defined(CONFIG_X86_32) |
---|
33 | 23 | #define ia32_sys_call_table sys_call_table |
---|
34 | | -#define __NR_syscall_compat_max __NR_syscall_max |
---|
35 | | -#define IA32_NR_syscalls NR_syscalls |
---|
36 | 24 | #endif |
---|
37 | 25 | |
---|
38 | 26 | #if defined(CONFIG_IA32_EMULATION) |
---|
39 | 27 | extern const sys_call_ptr_t ia32_sys_call_table[]; |
---|
| 28 | +#endif |
---|
| 29 | + |
---|
| 30 | +#ifdef CONFIG_X86_X32_ABI |
---|
| 31 | +extern const sys_call_ptr_t x32_sys_call_table[]; |
---|
40 | 32 | #endif |
---|
41 | 33 | |
---|
42 | 34 | /* |
---|
.. | .. |
---|
91 | 83 | |
---|
92 | 84 | static inline void syscall_get_arguments(struct task_struct *task, |
---|
93 | 85 | struct pt_regs *regs, |
---|
94 | | - unsigned int i, unsigned int n, |
---|
95 | 86 | unsigned long *args) |
---|
96 | 87 | { |
---|
97 | | - BUG_ON(i + n > 6); |
---|
98 | | - memcpy(args, ®s->bx + i, n * sizeof(args[0])); |
---|
| 88 | + memcpy(args, ®s->bx, 6 * sizeof(args[0])); |
---|
99 | 89 | } |
---|
100 | 90 | |
---|
101 | 91 | static inline void syscall_set_arguments(struct task_struct *task, |
---|
.. | .. |
---|
107 | 97 | memcpy(®s->bx + i, args, n * sizeof(args[0])); |
---|
108 | 98 | } |
---|
109 | 99 | |
---|
110 | | -static inline int syscall_get_arch(void) |
---|
| 100 | +static inline int syscall_get_arch(struct task_struct *task) |
---|
111 | 101 | { |
---|
112 | 102 | return AUDIT_ARCH_I386; |
---|
113 | 103 | } |
---|
.. | .. |
---|
116 | 106 | |
---|
117 | 107 | static inline void syscall_get_arguments(struct task_struct *task, |
---|
118 | 108 | struct pt_regs *regs, |
---|
119 | | - unsigned int i, unsigned int n, |
---|
120 | 109 | unsigned long *args) |
---|
121 | 110 | { |
---|
122 | 111 | # ifdef CONFIG_IA32_EMULATION |
---|
123 | | - if (task->thread_info.status & TS_COMPAT) |
---|
124 | | - switch (i) { |
---|
125 | | - case 0: |
---|
126 | | - if (!n--) break; |
---|
127 | | - *args++ = regs->bx; |
---|
128 | | - case 1: |
---|
129 | | - if (!n--) break; |
---|
130 | | - *args++ = regs->cx; |
---|
131 | | - case 2: |
---|
132 | | - if (!n--) break; |
---|
133 | | - *args++ = regs->dx; |
---|
134 | | - case 3: |
---|
135 | | - if (!n--) break; |
---|
136 | | - *args++ = regs->si; |
---|
137 | | - case 4: |
---|
138 | | - if (!n--) break; |
---|
139 | | - *args++ = regs->di; |
---|
140 | | - case 5: |
---|
141 | | - if (!n--) break; |
---|
142 | | - *args++ = regs->bp; |
---|
143 | | - case 6: |
---|
144 | | - if (!n--) break; |
---|
145 | | - default: |
---|
146 | | - BUG(); |
---|
147 | | - break; |
---|
148 | | - } |
---|
149 | | - else |
---|
| 112 | + if (task->thread_info.status & TS_COMPAT) { |
---|
| 113 | + *args++ = regs->bx; |
---|
| 114 | + *args++ = regs->cx; |
---|
| 115 | + *args++ = regs->dx; |
---|
| 116 | + *args++ = regs->si; |
---|
| 117 | + *args++ = regs->di; |
---|
| 118 | + *args = regs->bp; |
---|
| 119 | + } else |
---|
150 | 120 | # endif |
---|
151 | | - switch (i) { |
---|
152 | | - case 0: |
---|
153 | | - if (!n--) break; |
---|
154 | | - *args++ = regs->di; |
---|
155 | | - case 1: |
---|
156 | | - if (!n--) break; |
---|
157 | | - *args++ = regs->si; |
---|
158 | | - case 2: |
---|
159 | | - if (!n--) break; |
---|
160 | | - *args++ = regs->dx; |
---|
161 | | - case 3: |
---|
162 | | - if (!n--) break; |
---|
163 | | - *args++ = regs->r10; |
---|
164 | | - case 4: |
---|
165 | | - if (!n--) break; |
---|
166 | | - *args++ = regs->r8; |
---|
167 | | - case 5: |
---|
168 | | - if (!n--) break; |
---|
169 | | - *args++ = regs->r9; |
---|
170 | | - case 6: |
---|
171 | | - if (!n--) break; |
---|
172 | | - default: |
---|
173 | | - BUG(); |
---|
174 | | - break; |
---|
175 | | - } |
---|
| 121 | + { |
---|
| 122 | + *args++ = regs->di; |
---|
| 123 | + *args++ = regs->si; |
---|
| 124 | + *args++ = regs->dx; |
---|
| 125 | + *args++ = regs->r10; |
---|
| 126 | + *args++ = regs->r8; |
---|
| 127 | + *args = regs->r9; |
---|
| 128 | + } |
---|
176 | 129 | } |
---|
177 | 130 | |
---|
178 | 131 | static inline void syscall_set_arguments(struct task_struct *task, |
---|
179 | 132 | struct pt_regs *regs, |
---|
180 | | - unsigned int i, unsigned int n, |
---|
181 | 133 | const unsigned long *args) |
---|
182 | 134 | { |
---|
183 | 135 | # ifdef CONFIG_IA32_EMULATION |
---|
184 | | - if (task->thread_info.status & TS_COMPAT) |
---|
185 | | - switch (i) { |
---|
186 | | - case 0: |
---|
187 | | - if (!n--) break; |
---|
188 | | - regs->bx = *args++; |
---|
189 | | - case 1: |
---|
190 | | - if (!n--) break; |
---|
191 | | - regs->cx = *args++; |
---|
192 | | - case 2: |
---|
193 | | - if (!n--) break; |
---|
194 | | - regs->dx = *args++; |
---|
195 | | - case 3: |
---|
196 | | - if (!n--) break; |
---|
197 | | - regs->si = *args++; |
---|
198 | | - case 4: |
---|
199 | | - if (!n--) break; |
---|
200 | | - regs->di = *args++; |
---|
201 | | - case 5: |
---|
202 | | - if (!n--) break; |
---|
203 | | - regs->bp = *args++; |
---|
204 | | - case 6: |
---|
205 | | - if (!n--) break; |
---|
206 | | - default: |
---|
207 | | - BUG(); |
---|
208 | | - break; |
---|
209 | | - } |
---|
210 | | - else |
---|
| 136 | + if (task->thread_info.status & TS_COMPAT) { |
---|
| 137 | + regs->bx = *args++; |
---|
| 138 | + regs->cx = *args++; |
---|
| 139 | + regs->dx = *args++; |
---|
| 140 | + regs->si = *args++; |
---|
| 141 | + regs->di = *args++; |
---|
| 142 | + regs->bp = *args; |
---|
| 143 | + } else |
---|
211 | 144 | # endif |
---|
212 | | - switch (i) { |
---|
213 | | - case 0: |
---|
214 | | - if (!n--) break; |
---|
215 | | - regs->di = *args++; |
---|
216 | | - case 1: |
---|
217 | | - if (!n--) break; |
---|
218 | | - regs->si = *args++; |
---|
219 | | - case 2: |
---|
220 | | - if (!n--) break; |
---|
221 | | - regs->dx = *args++; |
---|
222 | | - case 3: |
---|
223 | | - if (!n--) break; |
---|
224 | | - regs->r10 = *args++; |
---|
225 | | - case 4: |
---|
226 | | - if (!n--) break; |
---|
227 | | - regs->r8 = *args++; |
---|
228 | | - case 5: |
---|
229 | | - if (!n--) break; |
---|
230 | | - regs->r9 = *args++; |
---|
231 | | - case 6: |
---|
232 | | - if (!n--) break; |
---|
233 | | - default: |
---|
234 | | - BUG(); |
---|
235 | | - break; |
---|
236 | | - } |
---|
| 145 | + { |
---|
| 146 | + regs->di = *args++; |
---|
| 147 | + regs->si = *args++; |
---|
| 148 | + regs->dx = *args++; |
---|
| 149 | + regs->r10 = *args++; |
---|
| 150 | + regs->r8 = *args++; |
---|
| 151 | + regs->r9 = *args; |
---|
| 152 | + } |
---|
237 | 153 | } |
---|
238 | 154 | |
---|
239 | | -static inline int syscall_get_arch(void) |
---|
| 155 | +static inline int syscall_get_arch(struct task_struct *task) |
---|
240 | 156 | { |
---|
241 | 157 | /* x32 tasks should be considered AUDIT_ARCH_X86_64. */ |
---|
242 | | - return in_ia32_syscall() ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64; |
---|
| 158 | + return (IS_ENABLED(CONFIG_IA32_EMULATION) && |
---|
| 159 | + task->thread_info.status & TS_COMPAT) |
---|
| 160 | + ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64; |
---|
243 | 161 | } |
---|
| 162 | + |
---|
| 163 | +void do_syscall_64(unsigned long nr, struct pt_regs *regs); |
---|
| 164 | +void do_int80_syscall_32(struct pt_regs *regs); |
---|
| 165 | +long do_fast_syscall_32(struct pt_regs *regs); |
---|
| 166 | + |
---|
244 | 167 | #endif /* CONFIG_X86_32 */ |
---|
245 | 168 | |
---|
246 | 169 | #endif /* _ASM_X86_SYSCALL_H */ |
---|