summaryrefslogtreecommitdiff
path: root/arch/tile/kernel/ptrace.c
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2013-11-22 18:57:08 -0500
committerEric Paris <eparis@redhat.com>2013-11-22 18:57:54 -0500
commitfc582aef7dcc27a7120cf232c1e76c569c7b6eab (patch)
tree7d275dd4ceab6067b91e9a25a5f6338b425fbccd /arch/tile/kernel/ptrace.c
parent9175c9d2aed528800175ef81c90569d00d23f9be (diff)
parent5e01dc7b26d9f24f39abace5da98ccbd6a5ceb52 (diff)
Merge tag 'v3.12'
Linux 3.12 Conflicts: fs/exec.c
Diffstat (limited to 'arch/tile/kernel/ptrace.c')
-rw-r--r--arch/tile/kernel/ptrace.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
index 0f83ed4602b2..de98c6ddf136 100644
--- a/arch/tile/kernel/ptrace.c
+++ b/arch/tile/kernel/ptrace.c
@@ -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);
}