Merge branch 'sfc-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc
[firefly-linux-kernel-4.4.55.git] / arch / tile / kernel / ptrace.c
index 0f83ed4602b2fb878bd8b110632b8b92bf49259c..de98c6ddf136dbeebee00b7d8b1c553cc8bf56c1 100644 (file)
@@ -265,6 +265,21 @@ int do_syscall_trace_enter(struct pt_regs *regs)
 
 void do_syscall_trace_exit(struct pt_regs *regs)
 {
+       long errno;
+
+       /*
+        * The standard tile calling convention returns the value (or negative
+        * errno) in r0, and zero (or positive errno) in r1.
+        * It saves a couple of cycles on the hot path to do this work in
+        * registers only as we return, rather than updating the in-memory
+        * struct ptregs.
+        */
+       errno = (long) regs->regs[0];
+       if (errno < 0 && errno > -4096)
+               regs->regs[1] = -errno;
+       else
+               regs->regs[1] = 0;
+
        if (test_thread_flag(TIF_SYSCALL_TRACE))
                tracehook_report_syscall_exit(regs, 0);
 
@@ -272,7 +287,7 @@ void do_syscall_trace_exit(struct pt_regs *regs)
                trace_sys_exit(regs, regs->regs[0]);
 }
 
-void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
+void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs)
 {
        struct siginfo info;
 
@@ -288,5 +303,5 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
 /* Handle synthetic interrupt delivered only by the simulator. */
 void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num)
 {
-       send_sigtrap(current, regs, fault_num);
+       send_sigtrap(current, regs);
 }