xtensa: fix system_call interaction with ptrace

[ Upstream commit 02ce94c229 ]

Don't overwrite return value if system call was cancelled at entry by
ptrace. Return status code from do_syscall_trace_enter so that
pt_regs::syscall doesn't need to be changed to skip syscall.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Max Filippov 2019-11-29 14:54:06 -08:00 committed by Greg Kroah-Hartman
parent f9f47ef869
commit a1a6f8a14c
2 changed files with 18 additions and 4 deletions

View File

@ -1897,6 +1897,7 @@ ENTRY(system_call)
mov a6, a2
call4 do_syscall_trace_enter
beqz a6, .Lsyscall_exit
l32i a7, a2, PT_SYSCALL
1:
@ -1911,8 +1912,6 @@ ENTRY(system_call)
addx4 a4, a7, a4
l32i a4, a4, 0
movi a5, sys_ni_syscall;
beq a4, a5, 1f
/* Load args: arg0 - arg5 are passed via regs. */
@ -1932,6 +1931,7 @@ ENTRY(system_call)
s32i a6, a2, PT_AREG2
bnez a3, 1f
.Lsyscall_exit:
abi_ret(4)
1:

View File

@ -542,14 +542,28 @@ long arch_ptrace(struct task_struct *child, long request,
return ret;
}
void do_syscall_trace_enter(struct pt_regs *regs)
void do_syscall_trace_leave(struct pt_regs *regs);
int do_syscall_trace_enter(struct pt_regs *regs)
{
if (regs->syscall == NO_SYSCALL)
regs->areg[2] = -ENOSYS;
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs))
tracehook_report_syscall_entry(regs)) {
regs->areg[2] = -ENOSYS;
regs->syscall = NO_SYSCALL;
return 0;
}
if (regs->syscall == NO_SYSCALL) {
do_syscall_trace_leave(regs);
return 0;
}
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, syscall_get_nr(current, regs));
return 1;
}
void do_syscall_trace_leave(struct pt_regs *regs)