aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2008-10-10 15:33:20 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-10-10 15:33:57 -0400
commit753c4dd6a2fa2af81f5d809d610d29f2d9dd9bc1 (patch)
treec6c1869a58357945e501b2eba3485ca154ee2f07
parentd86730bb9597b02bff59a3a5a01c0094d71a265f (diff)
[S390] ptrace changes
* System call parameter and result access functions * Add tracehook calls * Split syscall_trace into two functions do_syscall_trace_enter and do_syscall_trace_exit Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/Kconfig1
-rw-r--r--arch/s390/include/asm/ptrace.h1
-rw-r--r--arch/s390/include/asm/syscall.h80
-rw-r--r--arch/s390/include/asm/thread_info.h2
-rw-r--r--arch/s390/kernel/entry.S50
-rw-r--r--arch/s390/kernel/entry64.S42
-rw-r--r--arch/s390/kernel/ptrace.c61
-rw-r--r--arch/s390/kernel/signal.c13
8 files changed, 202 insertions, 48 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 8d41908e2513..4c03049e7db9 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -74,6 +74,7 @@ config S390
74 select HAVE_KPROBES 74 select HAVE_KPROBES
75 select HAVE_KRETPROBES 75 select HAVE_KRETPROBES
76 select HAVE_KVM if 64BIT 76 select HAVE_KVM if 64BIT
77 select HAVE_ARCH_TRACEHOOK
77 78
78source "init/Kconfig" 79source "init/Kconfig"
79 80
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index af2c9ac28a07..a7226f8143fb 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -490,6 +490,7 @@ extern void user_disable_single_step(struct task_struct *);
490 490
491#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) 491#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
492#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) 492#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
493#define user_stack_pointer(regs)((regs)->gprs[15])
493#define regs_return_value(regs)((regs)->gprs[2]) 494#define regs_return_value(regs)((regs)->gprs[2])
494#define profile_pc(regs) instruction_pointer(regs) 495#define profile_pc(regs) instruction_pointer(regs)
495extern void show_regs(struct pt_regs * regs); 496extern void show_regs(struct pt_regs * regs);
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h
new file mode 100644
index 000000000000..6e623971fbb9
--- /dev/null
+++ b/arch/s390/include/asm/syscall.h
@@ -0,0 +1,80 @@
1/*
2 * Access to user system call parameters and results
3 *
4 * Copyright IBM Corp. 2008
5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License (version 2 only)
9 * as published by the Free Software Foundation.
10 */
11
12#ifndef _ASM_SYSCALL_H
13#define _ASM_SYSCALL_H 1
14
15#include <asm/ptrace.h>
16
17static inline long syscall_get_nr(struct task_struct *task,
18 struct pt_regs *regs)
19{
20 if (regs->trap != __LC_SVC_OLD_PSW)
21 return -1;
22 return regs->gprs[2];
23}
24
25static inline void syscall_rollback(struct task_struct *task,
26 struct pt_regs *regs)
27{
28 regs->gprs[2] = regs->orig_gpr2;
29}
30
31static inline long syscall_get_error(struct task_struct *task,
32 struct pt_regs *regs)
33{
34 return (regs->gprs[2] >= -4096UL) ? -regs->gprs[2] : 0;
35}
36
37static inline long syscall_get_return_value(struct task_struct *task,
38 struct pt_regs *regs)
39{
40 return regs->gprs[2];
41}
42
43static inline void syscall_set_return_value(struct task_struct *task,
44 struct pt_regs *regs,
45 int error, long val)
46{
47 regs->gprs[2] = error ? -error : val;
48}
49
50static inline void syscall_get_arguments(struct task_struct *task,
51 struct pt_regs *regs,
52 unsigned int i, unsigned int n,
53 unsigned long *args)
54{
55 BUG_ON(i + n > 6);
56#ifdef CONFIG_COMPAT
57 if (test_tsk_thread_flag(task, TIF_31BIT)) {
58 if (i + n == 6)
59 args[--n] = (u32) regs->args[0];
60 while (n-- > 0)
61 args[n] = (u32) regs->gprs[2 + i + n];
62 }
63#endif
64 if (i + n == 6)
65 args[--n] = regs->args[0];
66 memcpy(args, &regs->gprs[2 + i], n * sizeof(args[0]));
67}
68
69static inline void syscall_set_arguments(struct task_struct *task,
70 struct pt_regs *regs,
71 unsigned int i, unsigned int n,
72 const unsigned long *args)
73{
74 BUG_ON(i + n > 6);
75 if (i + n == 6)
76 regs->args[0] = args[--n];
77 memcpy(&regs->gprs[2 + i], args, n * sizeof(args[0]));
78}
79
80#endif /* _ASM_SYSCALL_H */
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index 91a8f93ad355..ea40a9d690fc 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -86,6 +86,7 @@ static inline struct thread_info *current_thread_info(void)
86 * thread information flags bit numbers 86 * thread information flags bit numbers
87 */ 87 */
88#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ 88#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
89#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
89#define TIF_SIGPENDING 2 /* signal pending */ 90#define TIF_SIGPENDING 2 /* signal pending */
90#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 91#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
91#define TIF_RESTART_SVC 4 /* restart svc with new svc number */ 92#define TIF_RESTART_SVC 4 /* restart svc with new svc number */
@@ -100,6 +101,7 @@ static inline struct thread_info *current_thread_info(void)
100#define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ 101#define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */
101 102
102#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 103#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
104#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
103#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) 105#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
104#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) 106#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
105#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 107#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 708cf9cf9a35..ed500ef799b7 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -49,9 +49,9 @@ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
49SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP 49SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
50SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE 50SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
51 51
52_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ 52_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
53 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 53 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
54_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ 54_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
55 _TIF_MCCK_PENDING) 55 _TIF_MCCK_PENDING)
56 56
57STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 57STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
@@ -318,6 +318,8 @@ sysc_work:
318 bo BASED(sysc_reschedule) 318 bo BASED(sysc_reschedule)
319 tm __TI_flags+3(%r9),_TIF_SIGPENDING 319 tm __TI_flags+3(%r9),_TIF_SIGPENDING
320 bnz BASED(sysc_sigpending) 320 bnz BASED(sysc_sigpending)
321 tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
322 bnz BASED(sysc_notify_resume)
321 tm __TI_flags+3(%r9),_TIF_RESTART_SVC 323 tm __TI_flags+3(%r9),_TIF_RESTART_SVC
322 bo BASED(sysc_restart) 324 bo BASED(sysc_restart)
323 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP 325 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
@@ -356,6 +358,16 @@ sysc_sigpending:
356 b BASED(sysc_work_loop) 358 b BASED(sysc_work_loop)
357 359
358# 360#
361# _TIF_NOTIFY_RESUME is set, call do_notify_resume
362#
363sysc_notify_resume:
364 la %r2,SP_PTREGS(%r15) # load pt_regs
365 l %r1,BASED(.Ldo_notify_resume)
366 la %r14,BASED(sysc_work_loop)
367 br %r1 # call do_notify_resume
368
369
370#
359# _TIF_RESTART_SVC is set, set up registers and restart svc 371# _TIF_RESTART_SVC is set, set up registers and restart svc
360# 372#
361sysc_restart: 373sysc_restart:
@@ -378,20 +390,21 @@ sysc_singlestep:
378 br %r1 # branch to do_single_step 390 br %r1 # branch to do_single_step
379 391
380# 392#
381# call trace before and after sys_call 393# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
394# and after the system call
382# 395#
383sysc_tracesys: 396sysc_tracesys:
384 l %r1,BASED(.Ltrace) 397 l %r1,BASED(.Ltrace_entry)
385 la %r2,SP_PTREGS(%r15) # load pt_regs 398 la %r2,SP_PTREGS(%r15) # load pt_regs
386 la %r3,0 399 la %r3,0
387 srl %r7,2 400 srl %r7,2
388 st %r7,SP_R2(%r15) 401 st %r7,SP_R2(%r15)
389 basr %r14,%r1 402 basr %r14,%r1
390 clc SP_R2(4,%r15),BASED(.Lnr_syscalls) 403 cl %r2,BASED(.Lnr_syscalls)
391 bnl BASED(sysc_tracenogo) 404 bnl BASED(sysc_tracenogo)
392 l %r8,BASED(.Lsysc_table) 405 l %r8,BASED(.Lsysc_table)
393 l %r7,SP_R2(%r15) # strace might have changed the 406 lr %r7,%r2
394 sll %r7,2 # system call 407 sll %r7,2 # *4
395 l %r8,0(%r7,%r8) 408 l %r8,0(%r7,%r8)
396sysc_tracego: 409sysc_tracego:
397 lm %r3,%r6,SP_R3(%r15) 410 lm %r3,%r6,SP_R3(%r15)
@@ -401,9 +414,8 @@ sysc_tracego:
401sysc_tracenogo: 414sysc_tracenogo:
402 tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) 415 tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
403 bz BASED(sysc_return) 416 bz BASED(sysc_return)
404 l %r1,BASED(.Ltrace) 417 l %r1,BASED(.Ltrace_exit)
405 la %r2,SP_PTREGS(%r15) # load pt_regs 418 la %r2,SP_PTREGS(%r15) # load pt_regs
406 la %r3,1
407 la %r14,BASED(sysc_return) 419 la %r14,BASED(sysc_return)
408 br %r1 420 br %r1
409 421
@@ -666,6 +678,8 @@ io_work_loop:
666 bo BASED(io_reschedule) 678 bo BASED(io_reschedule)
667 tm __TI_flags+3(%r9),_TIF_SIGPENDING 679 tm __TI_flags+3(%r9),_TIF_SIGPENDING
668 bnz BASED(io_sigpending) 680 bnz BASED(io_sigpending)
681 tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
682 bnz BASED(io_notify_resume)
669 b BASED(io_restore) 683 b BASED(io_restore)
670io_work_done: 684io_work_done:
671 685
@@ -704,6 +718,19 @@ io_sigpending:
704 TRACE_IRQS_OFF 718 TRACE_IRQS_OFF
705 b BASED(io_work_loop) 719 b BASED(io_work_loop)
706 720
721#
722# _TIF_SIGPENDING is set, call do_signal
723#
724io_notify_resume:
725 TRACE_IRQS_ON
726 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
727 la %r2,SP_PTREGS(%r15) # load pt_regs
728 l %r1,BASED(.Ldo_notify_resume)
729 basr %r14,%r1 # call do_signal
730 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
731 TRACE_IRQS_OFF
732 b BASED(io_work_loop)
733
707/* 734/*
708 * External interrupt handler routine 735 * External interrupt handler routine
709 */ 736 */
@@ -1070,6 +1097,8 @@ cleanup_io_leave_insn:
1070.Ldo_IRQ: .long do_IRQ 1097.Ldo_IRQ: .long do_IRQ
1071.Ldo_extint: .long do_extint 1098.Ldo_extint: .long do_extint
1072.Ldo_signal: .long do_signal 1099.Ldo_signal: .long do_signal
1100.Ldo_notify_resume:
1101 .long do_notify_resume
1073.Lhandle_per: .long do_single_step 1102.Lhandle_per: .long do_single_step
1074.Ldo_execve: .long do_execve 1103.Ldo_execve: .long do_execve
1075.Lexecve_tail: .long execve_tail 1104.Lexecve_tail: .long execve_tail
@@ -1079,7 +1108,8 @@ cleanup_io_leave_insn:
1079.Lpreempt_schedule_irq: 1108.Lpreempt_schedule_irq:
1080 .long preempt_schedule_irq 1109 .long preempt_schedule_irq
1081#endif 1110#endif
1082.Ltrace: .long syscall_trace 1111.Ltrace_entry: .long do_syscall_trace_enter
1112.Ltrace_exit: .long do_syscall_trace_exit
1083.Lschedtail: .long schedule_tail 1113.Lschedtail: .long schedule_tail
1084.Lsysc_table: .long sys_call_table 1114.Lsysc_table: .long sys_call_table
1085#ifdef CONFIG_TRACE_IRQFLAGS 1115#ifdef CONFIG_TRACE_IRQFLAGS
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index fee10177dbfc..d7ce150453f2 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -52,9 +52,9 @@ SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
52STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 52STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
53STACK_SIZE = 1 << STACK_SHIFT 53STACK_SIZE = 1 << STACK_SHIFT
54 54
55_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ 55_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
56 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 56 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
57_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ 57_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
58 _TIF_MCCK_PENDING) 58 _TIF_MCCK_PENDING)
59 59
60#define BASED(name) name-system_call(%r13) 60#define BASED(name) name-system_call(%r13)
@@ -310,6 +310,8 @@ sysc_work:
310 jo sysc_reschedule 310 jo sysc_reschedule
311 tm __TI_flags+7(%r9),_TIF_SIGPENDING 311 tm __TI_flags+7(%r9),_TIF_SIGPENDING
312 jnz sysc_sigpending 312 jnz sysc_sigpending
313 tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME
314 jnz sysc_notify_resume
313 tm __TI_flags+7(%r9),_TIF_RESTART_SVC 315 tm __TI_flags+7(%r9),_TIF_RESTART_SVC
314 jo sysc_restart 316 jo sysc_restart
315 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP 317 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
@@ -345,6 +347,14 @@ sysc_sigpending:
345 j sysc_work_loop 347 j sysc_work_loop
346 348
347# 349#
350# _TIF_NOTIFY_RESUME is set, call do_notify_resume
351#
352sysc_notify_resume:
353 la %r2,SP_PTREGS(%r15) # load pt_regs
354 larl %r14,sysc_work_loop
355 jg do_notify_resume # call do_notify_resume
356
357#
348# _TIF_RESTART_SVC is set, set up registers and restart svc 358# _TIF_RESTART_SVC is set, set up registers and restart svc
349# 359#
350sysc_restart: 360sysc_restart:
@@ -367,20 +377,19 @@ sysc_singlestep:
367 jg do_single_step # branch to do_sigtrap 377 jg do_single_step # branch to do_sigtrap
368 378
369# 379#
370# call syscall_trace before and after system call 380# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
371# special linkage: %r12 contains the return address for trace_svc 381# and after the system call
372# 382#
373sysc_tracesys: 383sysc_tracesys:
374 la %r2,SP_PTREGS(%r15) # load pt_regs 384 la %r2,SP_PTREGS(%r15) # load pt_regs
375 la %r3,0 385 la %r3,0
376 srl %r7,2 386 srl %r7,2
377 stg %r7,SP_R2(%r15) 387 stg %r7,SP_R2(%r15)
378 brasl %r14,syscall_trace 388 brasl %r14,do_syscall_trace_enter
379 lghi %r0,NR_syscalls 389 lghi %r0,NR_syscalls
380 clg %r0,SP_R2(%r15) 390 clgr %r0,%r2
381 jnh sysc_tracenogo 391 jnh sysc_tracenogo
382 lg %r7,SP_R2(%r15) # strace might have changed the 392 slag %r7,%r2,2 # *4
383 sll %r7,2 # system call
384 lgf %r8,0(%r7,%r10) 393 lgf %r8,0(%r7,%r10)
385sysc_tracego: 394sysc_tracego:
386 lmg %r3,%r6,SP_R3(%r15) 395 lmg %r3,%r6,SP_R3(%r15)
@@ -391,9 +400,8 @@ sysc_tracenogo:
391 tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) 400 tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
392 jz sysc_return 401 jz sysc_return
393 la %r2,SP_PTREGS(%r15) # load pt_regs 402 la %r2,SP_PTREGS(%r15) # load pt_regs
394 la %r3,1
395 larl %r14,sysc_return # return point is sysc_return 403 larl %r14,sysc_return # return point is sysc_return
396 jg syscall_trace 404 jg do_syscall_trace_exit
397 405
398# 406#
399# a new process exits the kernel with ret_from_fork 407# a new process exits the kernel with ret_from_fork
@@ -672,6 +680,8 @@ io_work_loop:
672 jo io_reschedule 680 jo io_reschedule
673 tm __TI_flags+7(%r9),_TIF_SIGPENDING 681 tm __TI_flags+7(%r9),_TIF_SIGPENDING
674 jnz io_sigpending 682 jnz io_sigpending
683 tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME
684 jnz io_notify_resume
675 j io_restore 685 j io_restore
676io_work_done: 686io_work_done:
677 687
@@ -712,6 +722,18 @@ io_sigpending:
712 TRACE_IRQS_OFF 722 TRACE_IRQS_OFF
713 j io_work_loop 723 j io_work_loop
714 724
725#
726# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
727#
728io_notify_resume:
729 TRACE_IRQS_ON
730 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
731 la %r2,SP_PTREGS(%r15) # load pt_regs
732 brasl %r14,do_notify_resume # call do_notify_resume
733 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
734 TRACE_IRQS_OFF
735 j io_work_loop
736
715/* 737/*
716 * External interrupt handler routine 738 * External interrupt handler routine
717 */ 739 */
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index c8b08289eb87..1f31be1ecc4b 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -35,6 +35,7 @@
35#include <linux/signal.h> 35#include <linux/signal.h>
36#include <linux/elf.h> 36#include <linux/elf.h>
37#include <linux/regset.h> 37#include <linux/regset.h>
38#include <linux/tracehook.h>
38 39
39#include <asm/segment.h> 40#include <asm/segment.h>
40#include <asm/page.h> 41#include <asm/page.h>
@@ -639,40 +640,44 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
639} 640}
640#endif 641#endif
641 642
642asmlinkage void 643asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
643syscall_trace(struct pt_regs *regs, int entryexit)
644{ 644{
645 if (unlikely(current->audit_context) && entryexit) 645 long ret;
646 audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
647
648 if (!test_thread_flag(TIF_SYSCALL_TRACE))
649 goto out;
650 if (!(current->ptrace & PT_PTRACED))
651 goto out;
652 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
653 ? 0x80 : 0));
654 646
655 /* 647 /*
656 * If the debuffer has set an invalid system call number, 648 * The sysc_tracesys code in entry.S stored the system
657 * we prepare to skip the system call restart handling. 649 * call number to gprs[2].
658 */ 650 */
659 if (!entryexit && regs->gprs[2] >= NR_syscalls) 651 ret = regs->gprs[2];
652 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
653 (tracehook_report_syscall_entry(regs) ||
654 regs->gprs[2] >= NR_syscalls)) {
655 /*
656 * Tracing decided this syscall should not happen or the
657 * debugger stored an invalid system call number. Skip
658 * the system call and the system call restart handling.
659 */
660 regs->trap = -1; 660 regs->trap = -1;
661 661 ret = -1;
662 /*
663 * this isn't the same as continuing with a signal, but it will do
664 * for normal use. strace only continues with a signal if the
665 * stopping signal is not SIGTRAP. -brl
666 */
667 if (current->exit_code) {
668 send_sig(current->exit_code, current, 1);
669 current->exit_code = 0;
670 } 662 }
671 out: 663
672 if (unlikely(current->audit_context) && !entryexit) 664 if (unlikely(current->audit_context))
673 audit_syscall_entry(test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X, 665 audit_syscall_entry(test_thread_flag(TIF_31BIT) ?
674 regs->gprs[2], regs->orig_gpr2, regs->gprs[3], 666 AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
675 regs->gprs[4], regs->gprs[5]); 667 regs->gprs[2], regs->orig_gpr2,
668 regs->gprs[3], regs->gprs[4],
669 regs->gprs[5]);
670 return ret;
671}
672
673asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
674{
675 if (unlikely(current->audit_context))
676 audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),
677 regs->gprs[2]);
678
679 if (test_thread_flag(TIF_SYSCALL_TRACE))
680 tracehook_report_syscall_exit(regs, 0);
676} 681}
677 682
678/* 683/*
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index b97682040215..4f7fc3059a8e 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -24,6 +24,7 @@
24#include <linux/tty.h> 24#include <linux/tty.h>
25#include <linux/personality.h> 25#include <linux/personality.h>
26#include <linux/binfmts.h> 26#include <linux/binfmts.h>
27#include <linux/tracehook.h>
27#include <asm/ucontext.h> 28#include <asm/ucontext.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
29#include <asm/lowcore.h> 30#include <asm/lowcore.h>
@@ -507,6 +508,12 @@ void do_signal(struct pt_regs *regs)
507 */ 508 */
508 if (current->thread.per_info.single_step) 509 if (current->thread.per_info.single_step)
509 set_thread_flag(TIF_SINGLE_STEP); 510 set_thread_flag(TIF_SINGLE_STEP);
511
512 /*
513 * Let tracing know that we've done the handler setup.
514 */
515 tracehook_signal_handler(signr, &info, &ka, regs,
516 test_thread_flag(TIF_SINGLE_STEP));
510 } 517 }
511 return; 518 return;
512 } 519 }
@@ -526,3 +533,9 @@ void do_signal(struct pt_regs *regs)
526 set_thread_flag(TIF_RESTART_SVC); 533 set_thread_flag(TIF_RESTART_SVC);
527 } 534 }
528} 535}
536
537void do_notify_resume(struct pt_regs *regs)
538{
539 clear_thread_flag(TIF_NOTIFY_RESUME);
540 tracehook_notify_resume(regs);
541}