• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1992 Ross Biro
7  * Copyright (C) Linus Torvalds
8  * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
9  * Copyright (C) 1996 David S. Miller
10  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
11  * Copyright (C) 1999 MIPS Technologies, Inc.
12  * Copyright (C) 2000 Ulf Carlsson
13  *
14  * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit
15  * binaries.
16  */
17 #include <linux/compiler.h>
18 #include <linux/elf.h>
19 #include <linux/kernel.h>
20 #include <linux/sched.h>
21 #include <linux/mm.h>
22 #include <linux/errno.h>
23 #include <linux/ptrace.h>
24 #include <linux/regset.h>
25 #include <linux/smp.h>
26 #include <linux/user.h>
27 #include <linux/security.h>
28 #include <linux/tracehook.h>
29 #include <linux/audit.h>
30 #include <linux/seccomp.h>
31 #include <linux/ftrace.h>
32 
33 #include <asm/byteorder.h>
34 #include <asm/cpu.h>
35 #include <asm/dsp.h>
36 #include <asm/fpu.h>
37 #include <asm/mipsregs.h>
38 #include <asm/mipsmtregs.h>
39 #include <asm/pgtable.h>
40 #include <asm/page.h>
41 #include <asm/syscall.h>
42 #include <asm/uaccess.h>
43 #include <asm/bootinfo.h>
44 #include <asm/reg.h>
45 
46 #define CREATE_TRACE_POINTS
47 #include <trace/events/syscalls.h>
48 
49 /*
50  * Called by kernel/ptrace.c when detaching..
51  *
52  * Make sure single step bits etc are not set.
53  */
ptrace_disable(struct task_struct * child)54 void ptrace_disable(struct task_struct *child)
55 {
56 	/* Don't load the watchpoint registers for the ex-child. */
57 	clear_tsk_thread_flag(child, TIF_LOAD_WATCH);
58 }
59 
60 /*
61  * Read a general register set.  We always use the 64-bit format, even
62  * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
63  * Registers are sign extended to fill the available space.
64  */
ptrace_getregs(struct task_struct * child,__s64 __user * data)65 int ptrace_getregs(struct task_struct *child, __s64 __user *data)
66 {
67 	struct pt_regs *regs;
68 	int i;
69 
70 	if (!access_ok(VERIFY_WRITE, data, 38 * 8))
71 		return -EIO;
72 
73 	regs = task_pt_regs(child);
74 
75 	for (i = 0; i < 32; i++)
76 		__put_user((long)regs->regs[i], data + i);
77 	__put_user((long)regs->lo, data + EF_LO - EF_R0);
78 	__put_user((long)regs->hi, data + EF_HI - EF_R0);
79 	__put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
80 	__put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
81 	__put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
82 	__put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
83 
84 	return 0;
85 }
86 
87 /*
88  * Write a general register set.  As for PTRACE_GETREGS, we always use
89  * the 64-bit format.  On a 32-bit kernel only the lower order half
90  * (according to endianness) will be used.
91  */
ptrace_setregs(struct task_struct * child,__s64 __user * data)92 int ptrace_setregs(struct task_struct *child, __s64 __user *data)
93 {
94 	struct pt_regs *regs;
95 	int i;
96 
97 	if (!access_ok(VERIFY_READ, data, 38 * 8))
98 		return -EIO;
99 
100 	regs = task_pt_regs(child);
101 
102 	for (i = 0; i < 32; i++)
103 		__get_user(regs->regs[i], data + i);
104 	__get_user(regs->lo, data + EF_LO - EF_R0);
105 	__get_user(regs->hi, data + EF_HI - EF_R0);
106 	__get_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
107 
108 	/* badvaddr, status, and cause may not be written.  */
109 
110 	return 0;
111 }
112 
ptrace_getfpregs(struct task_struct * child,__u32 __user * data)113 int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
114 {
115 	int i;
116 	unsigned int tmp;
117 
118 	if (!access_ok(VERIFY_WRITE, data, 33 * 8))
119 		return -EIO;
120 
121 	if (tsk_used_math(child)) {
122 		fpureg_t *fregs = get_fpu_regs(child);
123 		for (i = 0; i < 32; i++)
124 			__put_user(fregs[i], i + (__u64 __user *) data);
125 	} else {
126 		for (i = 0; i < 32; i++)
127 			__put_user((__u64) -1, i + (__u64 __user *) data);
128 	}
129 
130 	__put_user(child->thread.fpu.fcr31, data + 64);
131 
132 	preempt_disable();
133 	if (cpu_has_fpu) {
134 		unsigned int flags;
135 
136 		if (cpu_has_mipsmt) {
137 			unsigned int vpflags = dvpe();
138 			flags = read_c0_status();
139 			__enable_fpu();
140 			__asm__ __volatile__(".set push\n.set hardfloat\ncfc1\t%0,$0\n.set pop" : "=r" (tmp));
141 			write_c0_status(flags);
142 			evpe(vpflags);
143 		} else {
144 			flags = read_c0_status();
145 			__enable_fpu();
146 			__asm__ __volatile__(".set push\n.set hardfloat\ncfc1\t%0,$0\n.set pop" : "=r" (tmp));
147 			write_c0_status(flags);
148 		}
149 	} else {
150 		tmp = 0;
151 	}
152 	preempt_enable();
153 	__put_user(tmp, data + 65);
154 
155 	return 0;
156 }
157 
ptrace_setfpregs(struct task_struct * child,__u32 __user * data)158 int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
159 {
160 	fpureg_t *fregs;
161 	int i;
162 
163 	if (!access_ok(VERIFY_READ, data, 33 * 8))
164 		return -EIO;
165 
166 	fregs = get_fpu_regs(child);
167 
168 	for (i = 0; i < 32; i++)
169 		__get_user(fregs[i], i + (__u64 __user *) data);
170 
171 	__get_user(child->thread.fpu.fcr31, data + 64);
172 
173 	/* FIR may not be written.  */
174 
175 	return 0;
176 }
177 
ptrace_get_watch_regs(struct task_struct * child,struct pt_watch_regs __user * addr)178 int ptrace_get_watch_regs(struct task_struct *child,
179 			  struct pt_watch_regs __user *addr)
180 {
181 	enum pt_watch_style style;
182 	int i;
183 
184 	if (!cpu_has_watch || current_cpu_data.watch_reg_use_cnt == 0)
185 		return -EIO;
186 	if (!access_ok(VERIFY_WRITE, addr, sizeof(struct pt_watch_regs)))
187 		return -EIO;
188 
189 #ifdef CONFIG_32BIT
190 	style = pt_watch_style_mips32;
191 #define WATCH_STYLE mips32
192 #else
193 	style = pt_watch_style_mips64;
194 #define WATCH_STYLE mips64
195 #endif
196 
197 	__put_user(style, &addr->style);
198 	__put_user(current_cpu_data.watch_reg_use_cnt,
199 		   &addr->WATCH_STYLE.num_valid);
200 	for (i = 0; i < current_cpu_data.watch_reg_use_cnt; i++) {
201 		__put_user(child->thread.watch.mips3264.watchlo[i],
202 			   &addr->WATCH_STYLE.watchlo[i]);
203 		__put_user(child->thread.watch.mips3264.watchhi[i] & 0xfff,
204 			   &addr->WATCH_STYLE.watchhi[i]);
205 		__put_user(current_cpu_data.watch_reg_masks[i],
206 			   &addr->WATCH_STYLE.watch_masks[i]);
207 	}
208 	for (; i < 8; i++) {
209 		__put_user(0, &addr->WATCH_STYLE.watchlo[i]);
210 		__put_user(0, &addr->WATCH_STYLE.watchhi[i]);
211 		__put_user(0, &addr->WATCH_STYLE.watch_masks[i]);
212 	}
213 
214 	return 0;
215 }
216 
ptrace_set_watch_regs(struct task_struct * child,struct pt_watch_regs __user * addr)217 int ptrace_set_watch_regs(struct task_struct *child,
218 			  struct pt_watch_regs __user *addr)
219 {
220 	int i;
221 	int watch_active = 0;
222 	unsigned long lt[NUM_WATCH_REGS];
223 	u16 ht[NUM_WATCH_REGS];
224 
225 	if (!cpu_has_watch || current_cpu_data.watch_reg_use_cnt == 0)
226 		return -EIO;
227 	if (!access_ok(VERIFY_READ, addr, sizeof(struct pt_watch_regs)))
228 		return -EIO;
229 	/* Check the values. */
230 	for (i = 0; i < current_cpu_data.watch_reg_use_cnt; i++) {
231 		__get_user(lt[i], &addr->WATCH_STYLE.watchlo[i]);
232 #ifdef CONFIG_32BIT
233 		if (lt[i] & __UA_LIMIT)
234 			return -EINVAL;
235 #else
236 		if (test_tsk_thread_flag(child, TIF_32BIT_ADDR)) {
237 			if (lt[i] & 0xffffffff80000000UL)
238 				return -EINVAL;
239 		} else {
240 			if (lt[i] & __UA_LIMIT)
241 				return -EINVAL;
242 		}
243 #endif
244 		__get_user(ht[i], &addr->WATCH_STYLE.watchhi[i]);
245 		if (ht[i] & ~0xff8)
246 			return -EINVAL;
247 	}
248 	/* Install them. */
249 	for (i = 0; i < current_cpu_data.watch_reg_use_cnt; i++) {
250 		if (lt[i] & 7)
251 			watch_active = 1;
252 		child->thread.watch.mips3264.watchlo[i] = lt[i];
253 		/* Set the G bit. */
254 		child->thread.watch.mips3264.watchhi[i] = ht[i];
255 	}
256 
257 	if (watch_active)
258 		set_tsk_thread_flag(child, TIF_LOAD_WATCH);
259 	else
260 		clear_tsk_thread_flag(child, TIF_LOAD_WATCH);
261 
262 	return 0;
263 }
264 
265 /* regset get/set implementations */
266 
gpr_get(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,void * kbuf,void __user * ubuf)267 static int gpr_get(struct task_struct *target,
268 		   const struct user_regset *regset,
269 		   unsigned int pos, unsigned int count,
270 		   void *kbuf, void __user *ubuf)
271 {
272 	struct pt_regs *regs = task_pt_regs(target);
273 
274 	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
275 				   regs, 0, sizeof(*regs));
276 }
277 
gpr_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)278 static int gpr_set(struct task_struct *target,
279 		   const struct user_regset *regset,
280 		   unsigned int pos, unsigned int count,
281 		   const void *kbuf, const void __user *ubuf)
282 {
283 	struct pt_regs newregs;
284 	int ret;
285 
286 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
287 				 &newregs,
288 				 0, sizeof(newregs));
289 	if (ret)
290 		return ret;
291 
292 	*task_pt_regs(target) = newregs;
293 
294 	return 0;
295 }
296 
fpr_get(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,void * kbuf,void __user * ubuf)297 static int fpr_get(struct task_struct *target,
298 		   const struct user_regset *regset,
299 		   unsigned int pos, unsigned int count,
300 		   void *kbuf, void __user *ubuf)
301 {
302 	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
303 				   &target->thread.fpu,
304 				   0, sizeof(elf_fpregset_t));
305 	/* XXX fcr31  */
306 }
307 
fpr_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)308 static int fpr_set(struct task_struct *target,
309 		   const struct user_regset *regset,
310 		   unsigned int pos, unsigned int count,
311 		   const void *kbuf, const void __user *ubuf)
312 {
313 	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
314 				  &target->thread.fpu,
315 				  0, sizeof(elf_fpregset_t));
316 	/* XXX fcr31  */
317 }
318 
319 enum mips_regset {
320 	REGSET_GPR,
321 	REGSET_FPR,
322 };
323 
324 static const struct user_regset mips_regsets[] = {
325 	[REGSET_GPR] = {
326 		.core_note_type	= NT_PRSTATUS,
327 		.n		= ELF_NGREG,
328 		.size		= sizeof(unsigned int),
329 		.align		= sizeof(unsigned int),
330 		.get		= gpr_get,
331 		.set		= gpr_set,
332 	},
333 	[REGSET_FPR] = {
334 		.core_note_type	= NT_PRFPREG,
335 		.n		= ELF_NFPREG,
336 		.size		= sizeof(elf_fpreg_t),
337 		.align		= sizeof(elf_fpreg_t),
338 		.get		= fpr_get,
339 		.set		= fpr_set,
340 	},
341 };
342 
343 static const struct user_regset_view user_mips_view = {
344 	.name		= "mips",
345 	.e_machine	= ELF_ARCH,
346 	.ei_osabi	= ELF_OSABI,
347 	.regsets	= mips_regsets,
348 	.n		= ARRAY_SIZE(mips_regsets),
349 };
350 
351 static const struct user_regset mips64_regsets[] = {
352 	[REGSET_GPR] = {
353 		.core_note_type	= NT_PRSTATUS,
354 		.n		= ELF_NGREG,
355 		.size		= sizeof(unsigned long),
356 		.align		= sizeof(unsigned long),
357 		.get		= gpr_get,
358 		.set		= gpr_set,
359 	},
360 	[REGSET_FPR] = {
361 		.core_note_type	= NT_PRFPREG,
362 		.n		= ELF_NFPREG,
363 		.size		= sizeof(elf_fpreg_t),
364 		.align		= sizeof(elf_fpreg_t),
365 		.get		= fpr_get,
366 		.set		= fpr_set,
367 	},
368 };
369 
370 static const struct user_regset_view user_mips64_view = {
371 	.name		= "mips",
372 	.e_machine	= ELF_ARCH,
373 	.ei_osabi	= ELF_OSABI,
374 	.regsets	= mips64_regsets,
375 	.n		= ARRAY_SIZE(mips_regsets),
376 };
377 
task_user_regset_view(struct task_struct * task)378 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
379 {
380 #ifdef CONFIG_32BIT
381 	return &user_mips_view;
382 #endif
383 
384 #ifdef CONFIG_MIPS32_O32
385 		if (test_thread_flag(TIF_32BIT_REGS))
386 			return &user_mips_view;
387 #endif
388 
389 	return &user_mips64_view;
390 }
391 
arch_ptrace(struct task_struct * child,long request,unsigned long addr,unsigned long data)392 long arch_ptrace(struct task_struct *child, long request,
393 		 unsigned long addr, unsigned long data)
394 {
395 	int ret;
396 	void __user *addrp = (void __user *) addr;
397 	void __user *datavp = (void __user *) data;
398 	unsigned long __user *datalp = (void __user *) data;
399 
400 	switch (request) {
401 	/* when I and D space are separate, these will need to be fixed. */
402 	case PTRACE_PEEKTEXT: /* read word at location addr. */
403 	case PTRACE_PEEKDATA:
404 		ret = generic_ptrace_peekdata(child, addr, data);
405 		break;
406 
407 	/* Read the word at location addr in the USER area. */
408 	case PTRACE_PEEKUSR: {
409 		struct pt_regs *regs;
410 		unsigned long tmp = 0;
411 
412 		regs = task_pt_regs(child);
413 		ret = 0;  /* Default return value. */
414 
415 		switch (addr) {
416 		case 0 ... 31:
417 			tmp = regs->regs[addr];
418 			break;
419 		case FPR_BASE ... FPR_BASE + 31:
420 			if (tsk_used_math(child)) {
421 				fpureg_t *fregs = get_fpu_regs(child);
422 
423 #ifdef CONFIG_32BIT
424 				/*
425 				 * The odd registers are actually the high
426 				 * order bits of the values stored in the even
427 				 * registers - unless we're using r2k_switch.S.
428 				 */
429 				if (addr & 1)
430 					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
431 				else
432 					tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
433 #endif
434 #ifdef CONFIG_64BIT
435 				tmp = fregs[addr - FPR_BASE];
436 #endif
437 			} else {
438 				tmp = -1;	/* FP not yet used  */
439 			}
440 			break;
441 		case PC:
442 			tmp = regs->cp0_epc;
443 			break;
444 		case CAUSE:
445 			tmp = regs->cp0_cause;
446 			break;
447 		case BADVADDR:
448 			tmp = regs->cp0_badvaddr;
449 			break;
450 		case MMHI:
451 			tmp = regs->hi;
452 			break;
453 		case MMLO:
454 			tmp = regs->lo;
455 			break;
456 #ifdef CONFIG_CPU_HAS_SMARTMIPS
457 		case ACX:
458 			tmp = regs->acx;
459 			break;
460 #endif
461 		case FPC_CSR:
462 			tmp = child->thread.fpu.fcr31;
463 			break;
464 		case FPC_EIR: {	/* implementation / version register */
465 			unsigned int flags;
466 #ifdef CONFIG_MIPS_MT_SMTC
467 			unsigned long irqflags;
468 			unsigned int mtflags;
469 #endif /* CONFIG_MIPS_MT_SMTC */
470 
471 			preempt_disable();
472 			if (!cpu_has_fpu) {
473 				preempt_enable();
474 				break;
475 			}
476 
477 #ifdef CONFIG_MIPS_MT_SMTC
478 			/* Read-modify-write of Status must be atomic */
479 			local_irq_save(irqflags);
480 			mtflags = dmt();
481 #endif /* CONFIG_MIPS_MT_SMTC */
482 			if (cpu_has_mipsmt) {
483 				unsigned int vpflags = dvpe();
484 				flags = read_c0_status();
485 				__enable_fpu();
486 				__asm__ __volatile__(".set push\n.set hardfloat\ncfc1\t%0,$0\n.set pop": "=r" (tmp));
487 				write_c0_status(flags);
488 				evpe(vpflags);
489 			} else {
490 				flags = read_c0_status();
491 				__enable_fpu();
492 				__asm__ __volatile__(".set push\n.set hardfloat\ncfc1\t%0,$0\n.set pop": "=r" (tmp));
493 				write_c0_status(flags);
494 			}
495 #ifdef CONFIG_MIPS_MT_SMTC
496 			emt(mtflags);
497 			local_irq_restore(irqflags);
498 #endif /* CONFIG_MIPS_MT_SMTC */
499 			preempt_enable();
500 			break;
501 		}
502 		case DSP_BASE ... DSP_BASE + 5: {
503 			dspreg_t *dregs;
504 
505 			if (!cpu_has_dsp) {
506 				tmp = 0;
507 				ret = -EIO;
508 				goto out;
509 			}
510 			dregs = __get_dsp_regs(child);
511 			tmp = (unsigned long) (dregs[addr - DSP_BASE]);
512 			break;
513 		}
514 		case DSP_CONTROL:
515 			if (!cpu_has_dsp) {
516 				tmp = 0;
517 				ret = -EIO;
518 				goto out;
519 			}
520 			tmp = child->thread.dsp.dspcontrol;
521 			break;
522 		default:
523 			tmp = 0;
524 			ret = -EIO;
525 			goto out;
526 		}
527 		ret = put_user(tmp, datalp);
528 		break;
529 	}
530 
531 	/* when I and D space are separate, this will have to be fixed. */
532 	case PTRACE_POKETEXT: /* write the word at location addr. */
533 	case PTRACE_POKEDATA:
534 		ret = generic_ptrace_pokedata(child, addr, data);
535 		break;
536 
537 	case PTRACE_POKEUSR: {
538 		struct pt_regs *regs;
539 		ret = 0;
540 		regs = task_pt_regs(child);
541 
542 		switch (addr) {
543 		case 0 ... 31:
544 			regs->regs[addr] = data;
545 			break;
546 		case FPR_BASE ... FPR_BASE + 31: {
547 			fpureg_t *fregs = get_fpu_regs(child);
548 
549 			if (!tsk_used_math(child)) {
550 				/* FP not yet used  */
551 				memset(&child->thread.fpu, ~0,
552 				       sizeof(child->thread.fpu));
553 				child->thread.fpu.fcr31 = 0;
554 			}
555 #ifdef CONFIG_32BIT
556 			/*
557 			 * The odd registers are actually the high order bits
558 			 * of the values stored in the even registers - unless
559 			 * we're using r2k_switch.S.
560 			 */
561 			if (addr & 1) {
562 				fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
563 				fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
564 			} else {
565 				fregs[addr - FPR_BASE] &= ~0xffffffffLL;
566 				fregs[addr - FPR_BASE] |= data;
567 			}
568 #endif
569 #ifdef CONFIG_64BIT
570 			fregs[addr - FPR_BASE] = data;
571 #endif
572 			break;
573 		}
574 		case PC:
575 			regs->cp0_epc = data;
576 			break;
577 		case MMHI:
578 			regs->hi = data;
579 			break;
580 		case MMLO:
581 			regs->lo = data;
582 			break;
583 #ifdef CONFIG_CPU_HAS_SMARTMIPS
584 		case ACX:
585 			regs->acx = data;
586 			break;
587 #endif
588 		case FPC_CSR:
589 			child->thread.fpu.fcr31 = data;
590 			break;
591 		case DSP_BASE ... DSP_BASE + 5: {
592 			dspreg_t *dregs;
593 
594 			if (!cpu_has_dsp) {
595 				ret = -EIO;
596 				break;
597 			}
598 
599 			dregs = __get_dsp_regs(child);
600 			dregs[addr - DSP_BASE] = data;
601 			break;
602 		}
603 		case DSP_CONTROL:
604 			if (!cpu_has_dsp) {
605 				ret = -EIO;
606 				break;
607 			}
608 			child->thread.dsp.dspcontrol = data;
609 			break;
610 		default:
611 			/* The rest are not allowed. */
612 			ret = -EIO;
613 			break;
614 		}
615 		break;
616 		}
617 
618 	case PTRACE_GETREGS:
619 		ret = ptrace_getregs(child, datavp);
620 		break;
621 
622 	case PTRACE_SETREGS:
623 		ret = ptrace_setregs(child, datavp);
624 		break;
625 
626 	case PTRACE_GETFPREGS:
627 		ret = ptrace_getfpregs(child, datavp);
628 		break;
629 
630 	case PTRACE_SETFPREGS:
631 		ret = ptrace_setfpregs(child, datavp);
632 		break;
633 
634 	case PTRACE_GET_THREAD_AREA:
635 		ret = put_user(task_thread_info(child)->tp_value, datalp);
636 		break;
637 
638 	case PTRACE_GET_WATCH_REGS:
639 		ret = ptrace_get_watch_regs(child, addrp);
640 		break;
641 
642 	case PTRACE_SET_WATCH_REGS:
643 		ret = ptrace_set_watch_regs(child, addrp);
644 		break;
645 
646 	default:
647 		ret = ptrace_request(child, request, addr, data);
648 		break;
649 	}
650  out:
651 	return ret;
652 }
653 
654 /*
655  * Notification of system call entry/exit
656  * - triggered by current->work.syscall_trace
657  */
syscall_trace_enter(struct pt_regs * regs,long syscall)658 asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
659 {
660 	long ret = 0;
661 
662 	if (secure_computing(syscall) == -1)
663 		return -1;
664 
665 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
666 	    tracehook_report_syscall_entry(regs))
667 		ret = -1;
668 
669 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
670 		trace_sys_enter(regs, regs->regs[2]);
671 
672 	audit_syscall_entry(syscall_get_arch(current, regs),
673 			    syscall,
674 			    regs->regs[4], regs->regs[5],
675 			    regs->regs[6], regs->regs[7]);
676 	return syscall;
677 }
678 
679 /*
680  * Notification of system call entry/exit
681  * - triggered by current->work.syscall_trace
682  */
syscall_trace_leave(struct pt_regs * regs)683 asmlinkage void syscall_trace_leave(struct pt_regs *regs)
684 {
685 	audit_syscall_exit(regs);
686 
687 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
688 		trace_sys_exit(regs, regs->regs[2]);
689 
690 	if (test_thread_flag(TIF_SYSCALL_TRACE))
691 		tracehook_report_syscall_exit(regs, 0);
692 }
693