diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-01-18 20:44:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-18 22:20:30 -0500 |
commit | f27201da5c8f118cfe266f51447bdd108d5f081d (patch) | |
tree | 9d889f4afec179b5b6f422b58dd36fa7606f3eee /arch/powerpc/kernel/signal_32.c | |
parent | 283828f3c19ceb3a64a8544d42cc189003e8b0fe (diff) |
[PATCH] TIF_RESTORE_SIGMASK support for arch/powerpc
Implement the TIF_RESTORE_SIGMASK flag in the new arch/powerpc kernel, for
both 32-bit and 64-bit system call paths.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 7f0d5ce2567d..3747ab0dac3f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -1128,7 +1128,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
1128 | { | 1128 | { |
1129 | siginfo_t info; | 1129 | siginfo_t info; |
1130 | struct k_sigaction ka; | 1130 | struct k_sigaction ka; |
1131 | unsigned int frame, newsp; | 1131 | unsigned int newsp; |
1132 | int signr, ret; | 1132 | int signr, ret; |
1133 | 1133 | ||
1134 | #ifdef CONFIG_PPC32 | 1134 | #ifdef CONFIG_PPC32 |
@@ -1139,11 +1139,11 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
1139 | } | 1139 | } |
1140 | #endif | 1140 | #endif |
1141 | 1141 | ||
1142 | if (!oldset) | 1142 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
1143 | oldset = ¤t->saved_sigmask; | ||
1144 | else if (!oldset) | ||
1143 | oldset = ¤t->blocked; | 1145 | oldset = ¤t->blocked; |
1144 | 1146 | ||
1145 | newsp = frame = 0; | ||
1146 | |||
1147 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 1147 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
1148 | #ifdef CONFIG_PPC32 | 1148 | #ifdef CONFIG_PPC32 |
1149 | no_signal: | 1149 | no_signal: |
@@ -1173,8 +1173,14 @@ no_signal: | |||
1173 | } | 1173 | } |
1174 | } | 1174 | } |
1175 | 1175 | ||
1176 | if (signr == 0) | 1176 | if (signr == 0) { |
1177 | /* No signal to deliver -- put the saved sigmask back */ | ||
1178 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
1179 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
1180 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
1181 | } | ||
1177 | return 0; /* no signals delivered */ | 1182 | return 0; /* no signals delivered */ |
1183 | } | ||
1178 | 1184 | ||
1179 | if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size | 1185 | if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size |
1180 | && !on_sig_stack(regs->gpr[1])) | 1186 | && !on_sig_stack(regs->gpr[1])) |
@@ -1207,6 +1213,10 @@ no_signal: | |||
1207 | sigaddset(¤t->blocked, signr); | 1213 | sigaddset(¤t->blocked, signr); |
1208 | recalc_sigpending(); | 1214 | recalc_sigpending(); |
1209 | spin_unlock_irq(¤t->sighand->siglock); | 1215 | spin_unlock_irq(¤t->sighand->siglock); |
1216 | /* A signal was successfully delivered; the saved sigmask is in | ||
1217 | its frame, and we can clear the TIF_RESTORE_SIGMASK flag */ | ||
1218 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
1219 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
1210 | } | 1220 | } |
1211 | 1221 | ||
1212 | return ret; | 1222 | return ret; |