aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/signal_32.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-06-04 01:15:52 -0400
committerPaul Mackerras <paulus@samba.org>2007-06-14 08:29:58 -0400
commitf478f5430c8a599f46c41e8172a507a5772a6b69 (patch)
treece42723ed517a82a5e73b45cfe52a3bd338c1a4d /arch/powerpc/kernel/signal_32.c
parentdb277e9a67b9d81b9d6cd74edf0c3e1a0ef2aa4b (diff)
[POWERPC] Consolidate do_signal
do_signal has exactly the same behaviour on 32bit and 64bit and 32bit compat on 64bit for handling 32bit signals. Consolidate all these into one common function in signal.c. The only odd left over is the try_to_free in the 32bit version that no other architecture has in mainline (only in i386 for some odd SuSE release). We should probably get rid of it in a separate patch. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r--arch/powerpc/kernel/signal_32.c88
1 files changed, 2 insertions, 86 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 1d899a56fa13..32481e71d71e 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -56,7 +56,6 @@
56#undef DEBUG_SIG 56#undef DEBUG_SIG
57 57
58#ifdef CONFIG_PPC64 58#ifdef CONFIG_PPC64
59#define do_signal do_signal32
60#define sys_sigsuspend compat_sys_sigsuspend 59#define sys_sigsuspend compat_sys_sigsuspend
61#define sys_rt_sigsuspend compat_sys_rt_sigsuspend 60#define sys_rt_sigsuspend compat_sys_rt_sigsuspend
62#define sys_rt_sigreturn compat_sys_rt_sigreturn 61#define sys_rt_sigreturn compat_sys_rt_sigreturn
@@ -231,8 +230,6 @@ static inline int restore_general_regs(struct pt_regs *regs,
231 230
232#endif /* CONFIG_PPC64 */ 231#endif /* CONFIG_PPC64 */
233 232
234int do_signal(sigset_t *oldset, struct pt_regs *regs);
235
236/* 233/*
237 * Atomically swap in the new signal mask, and wait for a signal. 234 * Atomically swap in the new signal mask, and wait for a signal.
238 */ 235 */
@@ -699,7 +696,7 @@ int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
699 * Set up a signal frame for a "real-time" signal handler 696 * Set up a signal frame for a "real-time" signal handler
700 * (one which gets siginfo). 697 * (one which gets siginfo).
701 */ 698 */
702static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, 699int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
703 siginfo_t *info, sigset_t *oldset, 700 siginfo_t *info, sigset_t *oldset,
704 struct pt_regs *regs, unsigned long newsp) 701 struct pt_regs *regs, unsigned long newsp)
705{ 702{
@@ -990,7 +987,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
990/* 987/*
991 * OK, we're invoking a handler 988 * OK, we're invoking a handler
992 */ 989 */
993static int handle_signal(unsigned long sig, struct k_sigaction *ka, 990int handle_signal32(unsigned long sig, struct k_sigaction *ka,
994 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, 991 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs,
995 unsigned long newsp) 992 unsigned long newsp)
996{ 993{
@@ -1101,84 +1098,3 @@ badframe:
1101 force_sig(SIGSEGV, current); 1098 force_sig(SIGSEGV, current);
1102 return 0; 1099 return 0;
1103} 1100}
1104
1105/*
1106 * Note that 'init' is a special process: it doesn't get signals it doesn't
1107 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1108 * mistake.
1109 */
1110int do_signal(sigset_t *oldset, struct pt_regs *regs)
1111{
1112 siginfo_t info;
1113 struct k_sigaction ka;
1114 unsigned int newsp;
1115 int signr, ret;
1116
1117#ifdef CONFIG_PPC32
1118 if (try_to_freeze()) {
1119 signr = 0;
1120 if (!signal_pending(current))
1121 goto no_signal;
1122 }
1123#endif
1124
1125 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1126 oldset = &current->saved_sigmask;
1127 else if (!oldset)
1128 oldset = &current->blocked;
1129
1130 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
1131#ifdef CONFIG_PPC32
1132no_signal:
1133#endif
1134 /* Is there any syscall restart business here ? */
1135 check_syscall_restart(regs, &ka, signr > 0);
1136
1137 if (signr == 0) {
1138 /* No signal to deliver -- put the saved sigmask back */
1139 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1140 clear_thread_flag(TIF_RESTORE_SIGMASK);
1141 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1142 }
1143 return 0; /* no signals delivered */
1144 }
1145
1146 if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
1147 && !on_sig_stack(regs->gpr[1]))
1148 newsp = current->sas_ss_sp + current->sas_ss_size;
1149 else
1150 newsp = regs->gpr[1];
1151 newsp &= ~0xfUL;
1152
1153#ifdef CONFIG_PPC64
1154 /*
1155 * Reenable the DABR before delivering the signal to
1156 * user space. The DABR will have been cleared if it
1157 * triggered inside the kernel.
1158 */
1159 if (current->thread.dabr)
1160 set_dabr(current->thread.dabr);
1161#endif
1162
1163 /* Whee! Actually deliver the signal. */
1164 if (ka.sa.sa_flags & SA_SIGINFO)
1165 ret = handle_rt_signal(signr, &ka, &info, oldset, regs, newsp);
1166 else
1167 ret = handle_signal(signr, &ka, &info, oldset, regs, newsp);
1168
1169 if (ret) {
1170 spin_lock_irq(&current->sighand->siglock);
1171 sigorsets(&current->blocked, &current->blocked,
1172 &ka.sa.sa_mask);
1173 if (!(ka.sa.sa_flags & SA_NODEFER))
1174 sigaddset(&current->blocked, signr);
1175 recalc_sigpending();
1176 spin_unlock_irq(&current->sighand->siglock);
1177 /* A signal was successfully delivered; the saved sigmask is in
1178 its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
1179 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1180 clear_thread_flag(TIF_RESTORE_SIGMASK);
1181 }
1182
1183 return ret;
1184}