xtensa: fix system_call interaction with ptrace
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>
This commit is contained in:
parent
ba9c1d6599
commit
02ce94c229
|
@ -1892,6 +1892,7 @@ ENTRY(system_call)
|
|||
|
||||
mov a6, a2
|
||||
call4 do_syscall_trace_enter
|
||||
beqz a6, .Lsyscall_exit
|
||||
l32i a7, a2, PT_SYSCALL
|
||||
|
||||
1:
|
||||
|
@ -1904,8 +1905,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. */
|
||||
|
||||
|
@ -1925,6 +1924,7 @@ ENTRY(system_call)
|
|||
|
||||
s32i a6, a2, PT_AREG2
|
||||
bnez a3, 1f
|
||||
.Lsyscall_exit:
|
||||
abi_ret(4)
|
||||
|
||||
1:
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue