aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/ia32
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-09-26 04:52:26 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:26 -0400
commit1d001df19d5323e642ba8ac821c713675ebccd82 (patch)
tree6eec46bca129524fc6e9ee55772a3943ff091a2f /arch/x86_64/ia32
parent3adbbcce9a49b900d4cc118cdccfdefa78bf1afb (diff)
[PATCH] Add TIF_RESTORE_SIGMASK
We need TIF_RESTORE_SIGMASK in order to support ppoll() and pselect() system calls. This patch originally came from Andi, and was based heavily on David Howells' implementation of same on i386. I fixed a typo which was causing do_signal() to use the wrong signal mask. Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/ia32')
-rw-r--r--arch/x86_64/ia32/ia32_signal.c28
1 files changed, 11 insertions, 17 deletions
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index 25e5ca22204c..549de439fb2d 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -113,25 +113,19 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
113} 113}
114 114
115asmlinkage long 115asmlinkage long
116sys32_sigsuspend(int history0, int history1, old_sigset_t mask, 116sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
117 struct pt_regs *regs)
118{ 117{
119 sigset_t saveset;
120
121 mask &= _BLOCKABLE; 118 mask &= _BLOCKABLE;
122 spin_lock_irq(&current->sighand->siglock); 119 spin_lock_irq(&current->sighand->siglock);
123 saveset = current->blocked; 120 current->saved_sigmask = current->blocked;
124 siginitset(&current->blocked, mask); 121 siginitset(&current->blocked, mask);
125 recalc_sigpending(); 122 recalc_sigpending();
126 spin_unlock_irq(&current->sighand->siglock); 123 spin_unlock_irq(&current->sighand->siglock);
127 124
128 regs->rax = -EINTR; 125 current->state = TASK_INTERRUPTIBLE;
129 while (1) { 126 schedule();
130 current->state = TASK_INTERRUPTIBLE; 127 set_thread_flag(TIF_RESTORE_SIGMASK);
131 schedule(); 128 return -ERESTARTNOHAND;
132 if (do_signal(regs, &saveset))
133 return -EINTR;
134 }
135} 129}
136 130
137asmlinkage long 131asmlinkage long
@@ -508,11 +502,11 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
508 current->comm, current->pid, frame, regs->rip, frame->pretcode); 502 current->comm, current->pid, frame, regs->rip, frame->pretcode);
509#endif 503#endif
510 504
511 return 1; 505 return 0;
512 506
513give_sigsegv: 507give_sigsegv:
514 force_sigsegv(sig, current); 508 force_sigsegv(sig, current);
515 return 0; 509 return -EFAULT;
516} 510}
517 511
518int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 512int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -595,7 +589,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
595 regs->ss = __USER32_DS; 589 regs->ss = __USER32_DS;
596 590
597 set_fs(USER_DS); 591 set_fs(USER_DS);
598 regs->eflags &= ~TF_MASK; 592 regs->eflags &= ~TF_MASK;
599 if (test_thread_flag(TIF_SINGLESTEP)) 593 if (test_thread_flag(TIF_SINGLESTEP))
600 ptrace_notify(SIGTRAP); 594 ptrace_notify(SIGTRAP);
601 595
@@ -604,9 +598,9 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
604 current->comm, current->pid, frame, regs->rip, frame->pretcode); 598 current->comm, current->pid, frame, regs->rip, frame->pretcode);
605#endif 599#endif
606 600
607 return 1; 601 return 0;
608 602
609give_sigsegv: 603give_sigsegv:
610 force_sigsegv(sig, current); 604 force_sigsegv(sig, current);
611 return 0; 605 return -EFAULT;
612} 606}