alpha: unb0rk sigsuspend() and rt_sigsuspend()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 18 Sep 2010 12:40:07 +0000 (08:40 -0400)
committerMatt Turner <mattst88@gmail.com>
Sun, 19 Sep 2010 03:08:28 +0000 (23:08 -0400)
commit392fb6e35400edbee183baba24b34a0fa2053813
treee11587c8b7ca75ab41b23f9e09e2c6a9365e2187
parent2deba1bd7126aadb5750beb927c878a6490065e6
alpha: unb0rk sigsuspend() and rt_sigsuspend()

Old code used to set regs->r0 and regs->r19 to force the right
return value.  Leaving that after switch to ERESTARTNOHAND
was a Bad Idea(tm), since now that screws the restart - if we
hit the case when get_signal_to_deliver() returns 0, we will
step back to syscall insn, with v0 set to EINTR and a3 to 1.
The latter won't matter, since EINTR is 4, aka __NR_write.

Testcase:

#include <signal.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>

main()
{
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCONT);
sigprocmask(SIG_SETMASK, &mask, NULL);
kill(0, SIGCONT);
syscall(__NR_sigsuspend, 1, "b0rken\n", 7);
}

results on alpha in immediate message to stdout...

Fix is obvious; moreover, since we don't need regs anymore, we can
switch to normal prototypes for these guys and lose the wrappers.
Even better, rt_sigsuspend() is identical to generic version in
kernel/signal.c now.

Tested-by: Michael Cree <mcree@orcon.net.nz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Matt Turner <mattst88@gmail.com>
arch/alpha/include/asm/unistd.h
arch/alpha/kernel/entry.S
arch/alpha/kernel/signal.c