From: Ed Swierk Date: Tue, 13 Jan 2015 05:10:30 +0000 (-0800) Subject: MIPS: Fix restart of indirect syscalls X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=e967ef022e00bb7c2e5b1a42007abfdd52055050;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git MIPS: Fix restart of indirect syscalls When 32-bit MIPS userspace invokes a syscall indirectly via syscall(number, arg1, ..., arg7), the kernel looks up the actual syscall based on the given number, shifts the other arguments to the left, and jumps to the syscall. If the syscall is interrupted by a signal and indicates it needs to be restarted by the kernel (by returning ERESTARTNOINTR for example), the syscall must be called directly, since the number is no longer the first argument, and the other arguments are now staged for a direct call. Before shifting the arguments, store the syscall number in pt_regs->regs[2]. This gets copied temporarily into pt_regs->regs[0] after the syscall returns. If the syscall needs to be restarted, handle_signal()/do_signal() copies the number back to pt_regs->reg[2], which ends up in $v0 once control returns to userspace. Signed-off-by: Ed Swierk Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8929/ Signed-off-by: Ralf Baechle --- diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index c5bf845c7dd4..6e8de80bb446 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -181,6 +181,7 @@ illegal_syscall: sll t1, t0, 2 beqz v0, einval lw t2, sys_call_table(t1) # syscall routine + sw a0, PT_R2(sp) # call routine directly on restart /* Some syscalls like execve get their arguments from struct pt_regs and claim zero arguments in the syscall table. Thus we have to diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 4fdca4fb7943..d07b210fbeff 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -186,6 +186,7 @@ LEAF(sys32_syscall) dsll t1, t0, 3 beqz v0, einval ld t2, sys32_call_table(t1) # syscall routine + sd a0, PT_R2(sp) # call routine directly on restart move a0, a1 # shift argument registers move a1, a2