openrisc: restore all regs on rt_sigreturn
authorJonas Bonn <jonas@southpole.se>
Mon, 23 Sep 2013 10:04:20 +0000 (12:04 +0200)
committerStafford Horne <shorne@gmail.com>
Mon, 12 Dec 2016 14:09:16 +0000 (23:09 +0900)
Fix signal handling for when signals are handled as the result of timers
or exceptions, previous code assumed syscalls. This was noticeable with X
crashing where it uses SIGALRM.

This patch restores all regs before returning to userspace via
_resume_userspace instead of via syscall return path.

The rt_sigreturn syscall is more like a context switch than a function
call; it entails a return from one context (the signal handler) to another
(the process in question).  For a context switch like this there are
effectively no call-saved regs that remain constant across the transition.

Reported-by: Sebastian Macke <sebastian@macke.de>
Signed-off-by: Jonas Bonn <jonas@southpole.se>
Tested-by: Guenter Roeck <linux@roeck-us.net>
[shorne@gmail.com: Updated comment better reflect change and issue]
Signed-off-by: Stafford Horne <shorne@gmail.com>
arch/openrisc/kernel/entry.S

index fec8bf97d806422ce76a578c83576733633a9bf6..572d223dbd2631e2dd8b7f56fc2db6332c55f6b8 100644 (file)
@@ -1101,8 +1101,16 @@ ENTRY(__sys_fork)
         l.addi r3,r1,0
 
 ENTRY(sys_rt_sigreturn)
-       l.j     _sys_rt_sigreturn
+       l.jal   _sys_rt_sigreturn
         l.addi r3,r1,0
+       l.sfne  r30,r0
+       l.bnf   _no_syscall_trace
+        l.nop
+       l.jal   do_syscall_trace_leave
+        l.addi r3,r1,0
+_no_syscall_trace:
+       l.j     _resume_userspace
+        l.nop
 
 /* This is a catch-all syscall for atomic instructions for the OpenRISC 1000.
  * The functions takes a variable number of parameters depending on which