.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * SuperH process tracing |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * Copyright (C) 2002 - 2009 Paul Mundt |
---|
6 | 7 | * |
---|
7 | 8 | * Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp> |
---|
8 | | - * |
---|
9 | | - * This file is subject to the terms and conditions of the GNU General Public |
---|
10 | | - * License. See the file "COPYING" in the main directory of this archive |
---|
11 | | - * for more details. |
---|
12 | 9 | */ |
---|
13 | 10 | #include <linux/kernel.h> |
---|
14 | 11 | #include <linux/sched.h> |
---|
.. | .. |
---|
28 | 25 | #include <linux/regset.h> |
---|
29 | 26 | #include <linux/hw_breakpoint.h> |
---|
30 | 27 | #include <linux/uaccess.h> |
---|
31 | | -#include <asm/pgtable.h> |
---|
32 | 28 | #include <asm/processor.h> |
---|
33 | 29 | #include <asm/mmu_context.h> |
---|
34 | 30 | #include <asm/syscalls.h> |
---|
.. | .. |
---|
138 | 134 | |
---|
139 | 135 | static int genregs_get(struct task_struct *target, |
---|
140 | 136 | const struct user_regset *regset, |
---|
141 | | - unsigned int pos, unsigned int count, |
---|
142 | | - void *kbuf, void __user *ubuf) |
---|
| 137 | + struct membuf to) |
---|
143 | 138 | { |
---|
144 | 139 | const struct pt_regs *regs = task_pt_regs(target); |
---|
145 | | - int ret; |
---|
146 | 140 | |
---|
147 | | - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
148 | | - regs->regs, |
---|
149 | | - 0, 16 * sizeof(unsigned long)); |
---|
150 | | - if (!ret) |
---|
151 | | - /* PC, PR, SR, GBR, MACH, MACL, TRA */ |
---|
152 | | - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
153 | | - ®s->pc, |
---|
154 | | - offsetof(struct pt_regs, pc), |
---|
155 | | - sizeof(struct pt_regs)); |
---|
156 | | - if (!ret) |
---|
157 | | - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, |
---|
158 | | - sizeof(struct pt_regs), -1); |
---|
159 | | - |
---|
160 | | - return ret; |
---|
| 141 | + return membuf_write(&to, regs, sizeof(struct pt_regs)); |
---|
161 | 142 | } |
---|
162 | 143 | |
---|
163 | 144 | static int genregs_set(struct task_struct *target, |
---|
.. | .. |
---|
184 | 165 | } |
---|
185 | 166 | |
---|
186 | 167 | #ifdef CONFIG_SH_FPU |
---|
187 | | -int fpregs_get(struct task_struct *target, |
---|
| 168 | +static int fpregs_get(struct task_struct *target, |
---|
188 | 169 | const struct user_regset *regset, |
---|
189 | | - unsigned int pos, unsigned int count, |
---|
190 | | - void *kbuf, void __user *ubuf) |
---|
| 170 | + struct membuf to) |
---|
191 | 171 | { |
---|
192 | 172 | int ret; |
---|
193 | 173 | |
---|
.. | .. |
---|
195 | 175 | if (ret) |
---|
196 | 176 | return ret; |
---|
197 | 177 | |
---|
198 | | - if ((boot_cpu_data.flags & CPU_HAS_FPU)) |
---|
199 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
200 | | - &target->thread.xstate->hardfpu, 0, -1); |
---|
201 | | - |
---|
202 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
203 | | - &target->thread.xstate->softfpu, 0, -1); |
---|
| 178 | + return membuf_write(&to, target->thread.xstate, |
---|
| 179 | + sizeof(struct user_fpu_struct)); |
---|
204 | 180 | } |
---|
205 | 181 | |
---|
206 | 182 | static int fpregs_set(struct task_struct *target, |
---|
.. | .. |
---|
234 | 210 | #ifdef CONFIG_SH_DSP |
---|
235 | 211 | static int dspregs_get(struct task_struct *target, |
---|
236 | 212 | const struct user_regset *regset, |
---|
237 | | - unsigned int pos, unsigned int count, |
---|
238 | | - void *kbuf, void __user *ubuf) |
---|
| 213 | + struct membuf to) |
---|
239 | 214 | { |
---|
240 | 215 | const struct pt_dspregs *regs = |
---|
241 | 216 | (struct pt_dspregs *)&target->thread.dsp_status.dsp_regs; |
---|
242 | | - int ret; |
---|
243 | 217 | |
---|
244 | | - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs, |
---|
245 | | - 0, sizeof(struct pt_dspregs)); |
---|
246 | | - if (!ret) |
---|
247 | | - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, |
---|
248 | | - sizeof(struct pt_dspregs), -1); |
---|
249 | | - |
---|
250 | | - return ret; |
---|
| 218 | + return membuf_write(&to, regs, sizeof(struct pt_dspregs)); |
---|
251 | 219 | } |
---|
252 | 220 | |
---|
253 | 221 | static int dspregs_set(struct task_struct *target, |
---|
.. | .. |
---|
328 | 296 | .n = ELF_NGREG, |
---|
329 | 297 | .size = sizeof(long), |
---|
330 | 298 | .align = sizeof(long), |
---|
331 | | - .get = genregs_get, |
---|
| 299 | + .regset_get = genregs_get, |
---|
332 | 300 | .set = genregs_set, |
---|
333 | 301 | }, |
---|
334 | 302 | |
---|
.. | .. |
---|
338 | 306 | .n = sizeof(struct user_fpu_struct) / sizeof(long), |
---|
339 | 307 | .size = sizeof(long), |
---|
340 | 308 | .align = sizeof(long), |
---|
341 | | - .get = fpregs_get, |
---|
| 309 | + .regset_get = fpregs_get, |
---|
342 | 310 | .set = fpregs_set, |
---|
343 | 311 | .active = fpregs_active, |
---|
344 | 312 | }, |
---|
.. | .. |
---|
349 | 317 | .n = sizeof(struct pt_dspregs) / sizeof(long), |
---|
350 | 318 | .size = sizeof(long), |
---|
351 | 319 | .align = sizeof(long), |
---|
352 | | - .get = dspregs_get, |
---|
| 320 | + .regset_get = dspregs_get, |
---|
353 | 321 | .set = dspregs_set, |
---|
354 | 322 | .active = dspregs_active, |
---|
355 | 323 | }, |
---|
.. | .. |
---|
487 | 455 | |
---|
488 | 456 | asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) |
---|
489 | 457 | { |
---|
490 | | - long ret = 0; |
---|
491 | | - |
---|
492 | | - secure_computing_strict(regs->regs[0]); |
---|
493 | | - |
---|
494 | 458 | if (test_thread_flag(TIF_SYSCALL_TRACE) && |
---|
495 | | - tracehook_report_syscall_entry(regs)) |
---|
496 | | - /* |
---|
497 | | - * Tracing decided this syscall should not happen. |
---|
498 | | - * We'll return a bogus call number to get an ENOSYS |
---|
499 | | - * error, but leave the original number in regs->regs[0]. |
---|
500 | | - */ |
---|
501 | | - ret = -1L; |
---|
| 459 | + tracehook_report_syscall_entry(regs)) { |
---|
| 460 | + regs->regs[0] = -ENOSYS; |
---|
| 461 | + return -1; |
---|
| 462 | + } |
---|
| 463 | + |
---|
| 464 | + if (secure_computing() == -1) |
---|
| 465 | + return -1; |
---|
502 | 466 | |
---|
503 | 467 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
---|
504 | 468 | trace_sys_enter(regs, regs->regs[0]); |
---|
.. | .. |
---|
506 | 470 | audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5], |
---|
507 | 471 | regs->regs[6], regs->regs[7]); |
---|
508 | 472 | |
---|
509 | | - return ret ?: regs->regs[0]; |
---|
| 473 | + return 0; |
---|
510 | 474 | } |
---|
511 | 475 | |
---|
512 | 476 | asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) |
---|