sh: Make syscall tracer use tracehook notifiers, add TIF_NOTIFY_RESUME.
[pandora-kernel.git] / arch / sh / kernel / ptrace_64.c
index 108f396..236d8be 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/syscalls.h>
 #include <linux/audit.h>
 #include <linux/seccomp.h>
+#include <linux/tracehook.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -221,40 +222,37 @@ asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
        return sys_ptrace(request, pid, addr, data);
 }
 
-asmlinkage void syscall_trace(struct pt_regs *regs, int entryexit)
+asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
 {
-       struct task_struct *tsk = current;
+       long long ret = 0;
 
        secure_computing(regs->regs[9]);
 
-       if (unlikely(current->audit_context) && entryexit)
-               audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
-                                  regs->regs[9]);
-
-       if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
-           !test_thread_flag(TIF_SINGLESTEP))
-               goto out;
-       if (!(tsk->ptrace & PT_PTRACED))
-               goto out;
-
-       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
-                               !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
-
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (tsk->exit_code) {
-               send_sig(tsk->exit_code, tsk, 1);
-               tsk->exit_code = 0;
-       }
+       if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+           tracehook_report_syscall_entry(regs))
+               /*
+                * Tracing decided this syscall should not happen.
+                * We'll return a bogus call number to get an ENOSYS
+                * error, but leave the original number in regs->regs[0].
+                */
+               ret = -1LL;
 
-out:
-       if (unlikely(current->audit_context) && !entryexit)
+       if (unlikely(current->audit_context))
                audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[1],
                                    regs->regs[2], regs->regs[3],
                                    regs->regs[4], regs->regs[5]);
+
+       return ret ?: regs->regs[9];
+}
+
+asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
+{
+       if (unlikely(current->audit_context))
+               audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
+                                  regs->regs[9]);
+
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
+               tracehook_report_syscall_exit(regs, 0);
 }
 
 /* Called with interrupts disabled */