aboutsummaryrefslogtreecommitdiffstats
path: root/arch/openrisc
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-02-14 06:40:56 -0500
committerJonas Bonn <jonas@southpole.se>2012-02-17 03:55:24 -0500
commite933c70de0e2590d41f5edd3133e7ee12b4e0bc6 (patch)
tree24269d0b02a250e4879be37629405263da5198dc /arch/openrisc
parentb675eeb743abaa0b99a35c1fd32fea8e13a17d32 (diff)
OpenRISC: Don't mask signals if we fail to setup signal stack
setup_rt_frame() needs to return an indication of whether it succeeded or failed in setting up the signal stack frame. If setup_rt_frame() fails then we must not modify current->blocked. Acked-by: Oleg Nesterov <oleg@redhat.com> Cc: Jonas Bonn <jonas@southpole.se> Cc: Arnd Bergmann <arnd@arndb.de> Cc: linux@lists.openrisc.net Signed-off-by: Matt Fleming <matt.fleming@intel.com> Signed-off-by: Jonas Bonn <jonas@southpole.se>
Diffstat (limited to 'arch/openrisc')
-rw-r--r--arch/openrisc/kernel/signal.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index 92d2218fcb97..14764e827a67 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -189,8 +189,8 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
189 * trampoline which performs the syscall sigreturn, or a provided 189 * trampoline which performs the syscall sigreturn, or a provided
190 * user-mode trampoline. 190 * user-mode trampoline.
191 */ 191 */
192static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 192static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
193 sigset_t *set, struct pt_regs *regs) 193 sigset_t *set, struct pt_regs *regs)
194{ 194{
195 struct rt_sigframe *frame; 195 struct rt_sigframe *frame;
196 unsigned long return_ip; 196 unsigned long return_ip;
@@ -247,18 +247,23 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
247 /* actually move the usp to reflect the stacked frame */ 247 /* actually move the usp to reflect the stacked frame */
248 regs->sp = (unsigned long)frame; 248 regs->sp = (unsigned long)frame;
249 249
250 return; 250 return 0;
251 251
252give_sigsegv: 252give_sigsegv:
253 force_sigsegv(sig, current); 253 force_sigsegv(sig, current);
254 return -EFAULT;
254} 255}
255 256
256static inline void 257static inline int
257handle_signal(unsigned long sig, 258handle_signal(unsigned long sig,
258 siginfo_t *info, struct k_sigaction *ka, 259 siginfo_t *info, struct k_sigaction *ka,
259 sigset_t *oldset, struct pt_regs *regs) 260 sigset_t *oldset, struct pt_regs *regs)
260{ 261{
261 setup_rt_frame(sig, ka, info, oldset, regs); 262 int ret;
263
264 ret = setup_rt_frame(sig, ka, info, oldset, regs);
265 if (ret)
266 return ret;
262 267
263 spin_lock_irq(&current->sighand->siglock); 268 spin_lock_irq(&current->sighand->siglock);
264 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask); 269 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
@@ -267,6 +272,8 @@ handle_signal(unsigned long sig,
267 recalc_sigpending(); 272 recalc_sigpending();
268 273
269 spin_unlock_irq(&current->sighand->siglock); 274 spin_unlock_irq(&current->sighand->siglock);
275
276 return 0;
270} 277}
271 278
272/* 279/*
@@ -355,13 +362,13 @@ void do_signal(struct pt_regs *regs)
355 oldset = &current->blocked; 362 oldset = &current->blocked;
356 363
357 /* Whee! Actually deliver the signal. */ 364 /* Whee! Actually deliver the signal. */
358 handle_signal(signr, &info, &ka, oldset, regs); 365 if (!handle_signal(signr, &info, &ka, oldset, regs)) {
359 /* a signal was successfully delivered; the saved 366 /* a signal was successfully delivered; the saved
360 * sigmask will have been stored in the signal frame, 367 * sigmask will have been stored in the signal frame,
361 * and will be restored by sigreturn, so we can simply 368 * and will be restored by sigreturn, so we can simply
362 * clear the TIF_RESTORE_SIGMASK flag */ 369 * clear the TIF_RESTORE_SIGMASK flag */
363 if (test_thread_flag(TIF_RESTORE_SIGMASK))
364 clear_thread_flag(TIF_RESTORE_SIGMASK); 370 clear_thread_flag(TIF_RESTORE_SIGMASK);
371 }
365 372
366 tracehook_signal_handler(signr, &info, &ka, regs, 373 tracehook_signal_handler(signr, &info, &ka, regs,
367 test_thread_flag(TIF_SINGLESTEP)); 374 test_thread_flag(TIF_SINGLESTEP));