#define instruction_pointer(regs) ((regs)->cp0_epc)
 #define profile_pc(regs) instruction_pointer(regs)
 
-extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
+extern asmlinkage void syscall_trace_enter(struct pt_regs *regs);
+extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
 
 extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;
 
 
        li      t0, _TIF_WORK_SYSCALL_EXIT
        and     t0, a2                  # a2 is preloaded with TI_FLAGS
        beqz    t0, work_pending        # trace bit set?
-       local_irq_enable                # could let do_syscall_trace()
+       local_irq_enable                # could let syscall_trace_leave()
                                        # call schedule() instead
        move    a0, sp
-       li      a1, 1
-       jal     do_syscall_trace
+       jal     syscall_trace_leave
        b       resume_userspace
 
 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT)
 
  * Notification of system call entry/exit
  * - triggered by current->work.syscall_trace
  */
-asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
+asmlinkage void syscall_trace_enter(struct pt_regs *regs)
 {
        /* do the secure computing check first */
-       if (!entryexit)
-               secure_computing(regs->regs[2]);
-
-       if (unlikely(current->audit_context) && entryexit)
-               audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]),
-                                  -regs->regs[2]);
+       secure_computing(regs->regs[2]);
 
        if (!(current->ptrace & PT_PTRACED))
                goto out;
        }
 
 out:
-       if (unlikely(current->audit_context) && !entryexit)
+       if (unlikely(current->audit_context))
                audit_syscall_entry(audit_arch(), regs->regs[2],
                                    regs->regs[4], regs->regs[5],
                                    regs->regs[6], regs->regs[7]);
 }
+
+/*
+ * Notification of system call entry/exit
+ * - triggered by current->work.syscall_trace
+ */
+asmlinkage void syscall_trace_leave(struct pt_regs *regs)
+{
+       if (unlikely(current->audit_context))
+               audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]),
+                                  -regs->regs[2]);
+
+       if (!(current->ptrace & PT_PTRACED))
+               return;
+
+       if (!test_thread_flag(TIF_SYSCALL_TRACE))
+               return;
+
+       /* The 0x80 provides a way for the tracing parent to distinguish
+          between a syscall stop and SIGTRAP delivery */
+       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
+                                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 (current->exit_code) {
+               send_sig(current->exit_code, current, 1);
+               current->exit_code = 0;
+       }
+}