aboutsummaryrefslogtreecommitdiff
path: root/arch/arc/kernel/signal.c
AgeCommit message (Collapse)Author
2015-04-19ARC: SA_SIGINFO ucontext regs off-by-oneVineet Gupta
commit 6914e1e3f63caa829431160f0f7093292daef2d5 upstream. The regfile provided to SA_SIGINFO signal handler as ucontext was off by one due to pt_regs gutter cleanups in 2013. Before handling signal, user pt_regs are copied onto user_regs_struct and copied back later. Both structs are binary compatible. This was all fine until commit 2fa919045b72 (ARC: pt_regs update #2) which removed the empty stack slot at top of pt_regs (corresponding to first pad) and made the corresponding fixup in struct user_regs_struct (the pad in there was moved out of @scratch - not removed altogether as it is part of ptrace ABI) struct user_regs_struct { + long pad; struct { - long pad; long bta, lp_start, lp_end,.... } scratch; ... } This meant that now user_regs_struct was off by 1 reg w.r.t pt_regs and signal code needs to user_regs_struct.scratch to reflect it as pt_regs, which is what this commit does. This problem was hidden for 2 years, because both save/restore, despite using wrong location, were using the same location. Only an interim inspection (reproducer below) exposed the issue. void handle_segv(int signo, siginfo_t *info, void *context) { ucontext_t *uc = context; struct user_regs_struct *regs = &(uc->uc_mcontext.regs); printf("regs %x %x\n", <=== prints 7 8 (vs. 8 9) regs->scratch.r8, regs->scratch.r9); } int main() { struct sigaction sa; sa.sa_sigaction = handle_segv; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, NULL); asm volatile( "mov r7, 7 \n" "mov r8, 8 \n" "mov r9, 9 \n" "mov r10, 10 \n" :::"r7","r8","r9","r10"); *((unsigned int*)0x10) = 0; } Fixes: 2fa919045b72ec892e "ARC: pt_regs update #2: Remove unused gutter at start of pt_regs" Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-10-03ARC: Fix signal frame management for SA_SIGINFOChristian Ruppert
Previously, when a signal was registered with SA_SIGINFO, parameters 2 and 3 of the signal handler were written to registers r1 and r2 before the register set was saved. This led to corruption of these two registers after returning from the signal handler (the wrong values were restored). With this patch, registers are now saved before any parameters are passed, thus maintaining the processor state from before signal entry. Signed-off-by: Christian Ruppert <christian.ruppert@abilis.com> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
2013-02-15ARC: [Review] Prevent incorrect syscall restartsVineet Gupta
Per Al Viro's "signals for dummies" https://lkml.org/lkml/2012/12/6/366 there are 3 golden rules for (not) restarting syscalls: " What we need to guarantee is * restarts do not happen on signals caught in interrupts or exceptions * restarts do not happen on signals caught in sigreturn() * restart should happen only once, even if we get through do_signal() many times." ARC Port already handled #1, this patch fixes #2 and #3. We use the additional state in pt_regs->orig_r8 to ckh if restarting has already been done once. Thanks to Al Viro for spotting this. Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Cc: Al Viro <viro@ZenIV.linux.org.uk>
2013-02-15ARC: Signal handlingVineet Gupta
Includes following fixes courtesy review by Al-Viro * Tracer poke to Callee-regs were lost Before going off into do_signal( ) we save the user-mode callee regs (as they are not saved by default as part of pt_regs). This is to make sure that that a Tracer (if tracing related signal) is able to do likes of PEEKUSR(callee-reg). However in return path we were simply discarding the user-mode callee regs, which would break a POKEUSR(callee-reg) from a tracer. * Issue related to multiple syscall restarts are addressed in next patch Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Cc: Al Viro <viro@ZenIV.linux.org.uk> Acked-by: Jonas Bonn <jonas@southpole.se>