aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-09-24 01:20:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-09-24 16:54:19 -0400
commita7f8388e2c167c73b6abb3b749157aafd08f90ee (patch)
tree361a61b35ee04b0684eb984d415ef121f1e751f8 /arch
parenta850ea30374ebed32a0724742601861853fde869 (diff)
m32r: fix rt_sigsuspend()
do_signal() should know about saved_mask for it to work... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/m32r/include/asm/signal.h1
-rw-r--r--arch/m32r/include/asm/unistd.h1
-rw-r--r--arch/m32r/kernel/entry.S3
-rw-r--r--arch/m32r/kernel/signal.c48
4 files changed, 14 insertions, 39 deletions
diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h
index 9c1acb2b1a92..b2eeb0de1c8d 100644
--- a/arch/m32r/include/asm/signal.h
+++ b/arch/m32r/include/asm/signal.h
@@ -157,7 +157,6 @@ typedef struct sigaltstack {
157#undef __HAVE_ARCH_SIG_BITOPS 157#undef __HAVE_ARCH_SIG_BITOPS
158 158
159struct pt_regs; 159struct pt_regs;
160extern int do_signal(struct pt_regs *regs, sigset_t *oldset);
161 160
162#define ptrace_signal_deliver(regs, cookie) do { } while (0) 161#define ptrace_signal_deliver(regs, cookie) do { } while (0)
163 162
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h
index 76125777483c..c70545689da8 100644
--- a/arch/m32r/include/asm/unistd.h
+++ b/arch/m32r/include/asm/unistd.h
@@ -351,6 +351,7 @@
351#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ 351#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
352#define __ARCH_WANT_SYS_OLDUMOUNT 352#define __ARCH_WANT_SYS_OLDUMOUNT
353#define __ARCH_WANT_SYS_RT_SIGACTION 353#define __ARCH_WANT_SYS_RT_SIGACTION
354#define __ARCH_WANT_SYS_RT_SIGSUSPEND
354 355
355#define __IGNORE_lchown 356#define __IGNORE_lchown
356#define __IGNORE_setuid 357#define __IGNORE_setuid
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 403869833b98..90149daa560f 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -235,8 +235,7 @@ work_resched:
235work_notifysig: ; deal with pending signals and 235work_notifysig: ; deal with pending signals and
236 ; notify-resume requests 236 ; notify-resume requests
237 mv r0, sp ; arg1 : struct pt_regs *regs 237 mv r0, sp ; arg1 : struct pt_regs *regs
238 ldi r1, #0 ; arg2 : sigset_t *oldset 238 ldi r1, r9 ; arg2 : __u32 thread_info_flags
239 mv r2, r9 ; arg3 : __u32 thread_info_flags
240 bl do_notify_resume 239 bl do_notify_resume
241 bra restore_all 240 bra restore_all
242 241
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 144b0f124fc7..acd69f7f3357 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -28,37 +28,6 @@
28 28
29#define DEBUG_SIG 0 29#define DEBUG_SIG 0
30 30
31#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
32
33int do_signal(struct pt_regs *, sigset_t *);
34
35asmlinkage int
36sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
37 unsigned long r2, unsigned long r3, unsigned long r4,
38 unsigned long r5, unsigned long r6, struct pt_regs *regs)
39{
40 sigset_t newset;
41
42 /* XXX: Don't preclude handling different sized sigset_t's. */
43 if (sigsetsize != sizeof(sigset_t))
44 return -EINVAL;
45
46 if (copy_from_user(&newset, unewset, sizeof(newset)))
47 return -EFAULT;
48 sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
49
50 spin_lock_irq(&current->sighand->siglock);
51 current->saved_sigmask = current->blocked;
52 current->blocked = newset;
53 recalc_sigpending();
54 spin_unlock_irq(&current->sighand->siglock);
55
56 current->state = TASK_INTERRUPTIBLE;
57 schedule();
58 set_thread_flag(TIF_RESTORE_SIGMASK);
59 return -ERESTARTNOHAND;
60}
61
62asmlinkage int 31asmlinkage int
63sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 32sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
64 unsigned long r2, unsigned long r3, unsigned long r4, 33 unsigned long r2, unsigned long r3, unsigned long r4,
@@ -332,12 +301,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
332 * want to handle. Thus you cannot kill init even with a SIGKILL even by 301 * want to handle. Thus you cannot kill init even with a SIGKILL even by
333 * mistake. 302 * mistake.
334 */ 303 */
335int do_signal(struct pt_regs *regs, sigset_t *oldset) 304static int do_signal(struct pt_regs *regs)
336{ 305{
337 siginfo_t info; 306 siginfo_t info;
338 int signr; 307 int signr;
339 struct k_sigaction ka; 308 struct k_sigaction ka;
340 unsigned short inst; 309 unsigned short inst;
310 sigset_t *oldset;
341 311
342 /* 312 /*
343 * We want the common case to go fast, which 313 * We want the common case to go fast, which
@@ -351,7 +321,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
351 if (try_to_freeze()) 321 if (try_to_freeze())
352 goto no_signal; 322 goto no_signal;
353 323
354 if (!oldset) 324 if (test_thread_flag(TIF_RESTORE_SIGMASK))
325 oldset = &current->saved_sigmask;
326 else
355 oldset = &current->blocked; 327 oldset = &current->blocked;
356 328
357 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 329 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -364,6 +336,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
364 336
365 /* Whee! Actually deliver the signal. */ 337 /* Whee! Actually deliver the signal. */
366 handle_signal(signr, &ka, &info, oldset, regs); 338 handle_signal(signr, &ka, &info, oldset, regs);
339 clear_thread_flag(TIF_RESTORE_SIGMASK);
367 return 1; 340 return 1;
368 } 341 }
369 342
@@ -391,6 +364,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
391 regs->bpc -= 4; 364 regs->bpc -= 4;
392 } 365 }
393 } 366 }
367 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
368 clear_thread_flag(TIF_RESTORE_SIGMASK);
369 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
370 }
394 return 0; 371 return 0;
395} 372}
396 373
@@ -398,8 +375,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
398 * notification of userspace execution resumption 375 * notification of userspace execution resumption
399 * - triggered by current->work.notify_resume 376 * - triggered by current->work.notify_resume
400 */ 377 */
401void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, 378void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
402 __u32 thread_info_flags)
403{ 379{
404 /* Pending single-step? */ 380 /* Pending single-step? */
405 if (thread_info_flags & _TIF_SINGLESTEP) 381 if (thread_info_flags & _TIF_SINGLESTEP)
@@ -407,7 +383,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
407 383
408 /* deal with pending signal delivery */ 384 /* deal with pending signal delivery */
409 if (thread_info_flags & _TIF_SIGPENDING) 385 if (thread_info_flags & _TIF_SIGPENDING)
410 do_signal(regs,oldset); 386 do_signal(regs);
411 387
412 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 388 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
413 clear_thread_flag(TIF_NOTIFY_RESUME); 389 clear_thread_flag(TIF_NOTIFY_RESUME);