diff options
Diffstat (limited to 'arch/s390/kernel/ptrace.c')
-rw-r--r-- | arch/s390/kernel/ptrace.c | 61 |
1 files changed, 33 insertions, 28 deletions
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 | ||
642 | asmlinkage void | 643 | asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) |
643 | syscall_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 | |||
673 | asmlinkage 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 | /* |