diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-04-22 06:59:07 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-05-22 05:58:06 +0200 |
commit | 9ccc9c75c9117d18a9b1f71a21f0066b1eb9db6f (patch) | |
tree | bbc68a45dc8e98dd12339e4c7df6a088a342bbf3 | |
parent | avr32: ->restart_block.fn needs to be reset on rt_sigreturn (diff) | |
download | linux-9ccc9c75c9117d18a9b1f71a21f0066b1eb9db6f.tar.xz linux-9ccc9c75c9117d18a9b1f71a21f0066b1eb9db6f.zip |
xtensa: switch to generic rt_sigsuspend(2)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/xtensa/include/asm/syscall.h | 2 | ||||
-rw-r--r-- | arch/xtensa/include/asm/unistd.h | 2 | ||||
-rw-r--r-- | arch/xtensa/kernel/entry.S | 1 | ||||
-rw-r--r-- | arch/xtensa/kernel/signal.c | 54 |
4 files changed, 16 insertions, 43 deletions
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h index efcf33b92e4c..fc289f7e8ebc 100644 --- a/arch/xtensa/include/asm/syscall.h +++ b/arch/xtensa/include/asm/syscall.h @@ -15,8 +15,6 @@ asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); asmlinkage long xtensa_ptrace(long, long, long, long); asmlinkage long xtensa_sigreturn(struct pt_regs*); asmlinkage long xtensa_rt_sigreturn(struct pt_regs*); -asmlinkage long xtensa_sigsuspend(struct pt_regs*); -asmlinkage long xtensa_rt_sigsuspend(struct pt_regs*); asmlinkage long xtensa_sigaction(int, const struct old_sigaction*, struct old_sigaction*); asmlinkage long xtensa_sigaltstack(struct pt_regs *regs); diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h index 798ee6d285a1..bc7e005faa60 100644 --- a/arch/xtensa/include/asm/unistd.h +++ b/arch/xtensa/include/asm/unistd.h @@ -507,7 +507,7 @@ __SYSCALL(229, sys_rt_sigtimedwait, 4) #define __NR_rt_sigqueueinfo 230 __SYSCALL(230, sys_rt_sigqueueinfo, 3) #define __NR_rt_sigsuspend 231 -__SYSCALL(231, xtensa_rt_sigsuspend, 2) +__SYSCALL(231, sys_rt_sigsuspend, 2) /* Message */ diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 6223f3346b5c..b1bb6d79d8b9 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -418,7 +418,6 @@ common_exception_return: movi a4, do_signal # int do_signal(struct pt_regs*, sigset_t*) mov a6, a1 - movi a7, 0 callx4 a4 j 1b diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 44e9329a6484..bb00cc470ca9 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -31,8 +31,6 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); - extern struct task_struct *coproc_owners[]; struct rt_sigframe @@ -429,37 +427,6 @@ give_sigsegv: return -EFAULT; } -/* - * Atomically swap in the new signal mask, and wait for a signal. - */ - -asmlinkage long xtensa_rt_sigsuspend(sigset_t __user *unewset, - size_t sigsetsize, - long a2, long a3, long a4, long a5, - struct pt_regs *regs) -{ - sigset_t saveset, newset; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) - return -EINVAL; - - if (copy_from_user(&newset, unewset, sizeof(newset))) - return -EFAULT; - - sigdelsetmask(&newset, ~_BLOCKABLE); - saveset = current->blocked; - set_current_blocked(&newset); - - regs->areg[2] = -EINTR; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(regs, &saveset)) - return -EINTR; - } -} - asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, long a2, long a3, long a4, long a5, @@ -479,19 +446,22 @@ asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, * the kernel can handle, and then we build all the user-level signal handling * stack-frames in one go after that. */ -int do_signal(struct pt_regs *regs, sigset_t *oldset) +void do_signal(struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; + sigset_t oldset; if (!user_mode(regs)) - return 0; + return; if (try_to_freeze()) goto no_signal; - if (!oldset) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else oldset = ¤t->blocked; task_pt_regs(current)->icountlevel = 0; @@ -535,13 +505,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* Set up the stack frame */ ret = setup_frame(signr, &ka, &info, oldset, regs); if (ret) - return ret; + return; + clear_thread_flag(TIF_RESTORE_SIGMASK); block_sigmask(&ka, signr); if (current->ptrace & PT_SINGLESTEP) task_pt_regs(current)->icountlevel = 1; - return 1; + return; } no_signal: @@ -561,8 +532,13 @@ no_signal: break; } } + + /* If there's no signal to deliver, we just restore the saved mask. */ + if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK)) + set_current_blocked(¤t->saved_sigmask); + if (current->ptrace & PT_SINGLESTEP) task_pt_regs(current)->icountlevel = 1; - return 0; + return; } |