diff options
author | Andi Kleen <ak@suse.de> | 2006-09-26 04:52:26 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:26 -0400 |
commit | 1d001df19d5323e642ba8ac821c713675ebccd82 (patch) | |
tree | 6eec46bca129524fc6e9ee55772a3943ff091a2f /arch/x86_64/ia32 | |
parent | 3adbbcce9a49b900d4cc118cdccfdefa78bf1afb (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.c | 28 |
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 | ||
115 | asmlinkage long | 115 | asmlinkage long |
116 | sys32_sigsuspend(int history0, int history1, old_sigset_t mask, | 116 | sys32_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(¤t->sighand->siglock); | 119 | spin_lock_irq(¤t->sighand->siglock); |
123 | saveset = current->blocked; | 120 | current->saved_sigmask = current->blocked; |
124 | siginitset(¤t->blocked, mask); | 121 | siginitset(¤t->blocked, mask); |
125 | recalc_sigpending(); | 122 | recalc_sigpending(); |
126 | spin_unlock_irq(¤t->sighand->siglock); | 123 | spin_unlock_irq(¤t->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 | ||
137 | asmlinkage long | 131 | asmlinkage 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 | ||
513 | give_sigsegv: | 507 | give_sigsegv: |
514 | force_sigsegv(sig, current); | 508 | force_sigsegv(sig, current); |
515 | return 0; | 509 | return -EFAULT; |
516 | } | 510 | } |
517 | 511 | ||
518 | int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 512 | int 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 | ||
609 | give_sigsegv: | 603 | give_sigsegv: |
610 | force_sigsegv(sig, current); | 604 | force_sigsegv(sig, current); |
611 | return 0; | 605 | return -EFAULT; |
612 | } | 606 | } |