aboutsummaryrefslogtreecommitdiffstats
path: root/arch/h8300/kernel
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-04-22 01:30:05 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-05-21 23:58:07 -0400
commit7ae4e32a65148353db3458e3eb87117f25620ac5 (patch)
tree31a5f95370fb32cb22838332c54e9a364bd9b188 /arch/h8300/kernel
parent8b6c3309c94b7296614d7783eb259555a6be6f7e (diff)
h8300: switch to saved_sigmask-based sigsuspend/rt_sigsuspend
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/h8300/kernel')
-rw-r--r--arch/h8300/kernel/signal.c73
-rw-r--r--arch/h8300/kernel/syscalls.S6
2 files changed, 20 insertions, 59 deletions
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index 78e9b65df93e..b5e360a95519 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -49,56 +49,15 @@
49 49
50#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 50#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
51 51
52asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
53
54/* 52/*
55 * Atomically swap in the new signal mask, and wait for a signal. 53 * Atomically swap in the new signal mask, and wait for a signal.
56 */ 54 */
57asmlinkage int do_sigsuspend(struct pt_regs *regs)
58{
59 old_sigset_t mask = regs->er3;
60 sigset_t saveset, blocked;
61
62 saveset = current->blocked;
63
64 mask &= _BLOCKABLE;
65 siginitset(&blocked, mask);
66 set_current_blocked(&blocked);
67
68 regs->er0 = -EINTR;
69 while (1) {
70 current->state = TASK_INTERRUPTIBLE;
71 schedule();
72 if (do_signal(regs, &saveset))
73 return -EINTR;
74 }
75}
76
77asmlinkage int 55asmlinkage int
78do_rt_sigsuspend(struct pt_regs *regs) 56sys_sigsuspend(int unused1, int unused2, old_sigset_t mask)
79{ 57{
80 sigset_t *unewset = (sigset_t *)regs->er1; 58 sigset_t blocked;
81 size_t sigsetsize = (size_t)regs->er2; 59 siginitset(&blocked, mask);
82 sigset_t saveset, newset; 60 return sigsuspend(&blocked);
83
84 /* XXX: Don't preclude handling different sized sigset_t's. */
85 if (sigsetsize != sizeof(sigset_t))
86 return -EINVAL;
87
88 if (copy_from_user(&newset, unewset, sizeof(newset)))
89 return -EFAULT;
90 sigdelsetmask(&newset, ~_BLOCKABLE);
91
92 saveset = current->blocked;
93 set_current_blocked(&newset);
94
95 regs->er0 = -EINTR;
96 while (1) {
97 current->state = TASK_INTERRUPTIBLE;
98 schedule();
99 if (do_signal(regs, &saveset))
100 return -EINTR;
101 }
102} 61}
103 62
104asmlinkage int 63asmlinkage int
@@ -482,8 +441,10 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
482 else 441 else
483 ret = setup_frame(sig, ka, oldset, regs); 442 ret = setup_frame(sig, ka, oldset, regs);
484 443
485 if (!ret) 444 if (!ret) {
486 block_sigmask(ka, sig); 445 block_sigmask(ka, sig);
446 clear_thread_flag(TIF_RESTORE_SIGMASK);
447 }
487} 448}
488 449
489/* 450/*
@@ -491,11 +452,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
491 * want to handle. Thus you cannot kill init even with a SIGKILL even by 452 * want to handle. Thus you cannot kill init even with a SIGKILL even by
492 * mistake. 453 * mistake.
493 */ 454 */
494asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset) 455statis void do_signal(struct pt_regs *regs)
495{ 456{
496 siginfo_t info; 457 siginfo_t info;
497 int signr; 458 int signr;
498 struct k_sigaction ka; 459 struct k_sigaction ka;
460 sigset_t *oldset;
499 461
500 /* 462 /*
501 * We want the common case to go fast, which 463 * We want the common case to go fast, which
@@ -504,21 +466,23 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset)
504 * if so. 466 * if so.
505 */ 467 */
506 if ((regs->ccr & 0x10)) 468 if ((regs->ccr & 0x10))
507 return 1; 469 return;
508 470
509 if (try_to_freeze()) 471 if (try_to_freeze())
510 goto no_signal; 472 goto no_signal;
511 473
512 current->thread.esp0 = (unsigned long) regs; 474 current->thread.esp0 = (unsigned long) regs;
513 475
514 if (!oldset) 476 if (test_thread_flag(TIF_RESTORE_SIGMASK))
477 oldset = &current->saved_sigmask;
478 else
515 oldset = &current->blocked; 479 oldset = &current->blocked;
516 480
517 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 481 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
518 if (signr > 0) { 482 if (signr > 0) {
519 /* Whee! Actually deliver the signal. */ 483 /* Whee! Actually deliver the signal. */
520 handle_signal(signr, &info, &ka, oldset, regs); 484 handle_signal(signr, &info, &ka, oldset, regs);
521 return 1; 485 return;
522 } 486 }
523 no_signal: 487 no_signal:
524 /* Did we come from a system call? */ 488 /* Did we come from a system call? */
@@ -535,13 +499,16 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset)
535 regs->pc -= 2; 499 regs->pc -= 2;
536 } 500 }
537 } 501 }
538 return 0; 502
503 /* If there's no signal to deliver, we just restore the saved mask. */
504 if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK))
505 set_current_blocked(&current->saved_sigmask);
539} 506}
540 507
541asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) 508asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
542{ 509{
543 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 510 if (thread_info_flags & _TIF_SIGPENDING)
544 do_signal(regs, NULL); 511 do_signal(regs);
545 512
546 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 513 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
547 clear_thread_flag(TIF_NOTIFY_RESUME); 514 clear_thread_flag(TIF_NOTIFY_RESUME);
diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S
index 4be2ea2fbe26..9d77e715a2ed 100644
--- a/arch/h8300/kernel/syscalls.S
+++ b/arch/h8300/kernel/syscalls.S
@@ -343,12 +343,6 @@ SYMBOL_NAME_LABEL(sys_call_table)
343SYMBOL_NAME_LABEL(sys_clone) 343SYMBOL_NAME_LABEL(sys_clone)
344 call_sp h8300_clone 344 call_sp h8300_clone
345 345
346SYMBOL_NAME_LABEL(sys_sigsuspend)
347 call_sp do_sigsuspend
348
349SYMBOL_NAME_LABEL(sys_rt_sigsuspend)
350 call_sp do_rt_sigsuspend
351
352SYMBOL_NAME_LABEL(sys_sigreturn) 346SYMBOL_NAME_LABEL(sys_sigreturn)
353 call_sp do_sigreturn 347 call_sp do_sigreturn
354 348