aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/signal.c')
-rw-r--r--arch/mips/kernel/signal.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index b3273aeaeedc..604f077bb5bf 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -550,23 +550,26 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
550 struct mips_abi *abi = current->thread.abi; 550 struct mips_abi *abi = current->thread.abi;
551 void *vdso = current->mm->context.vdso; 551 void *vdso = current->mm->context.vdso;
552 552
553 switch(regs->regs[0]) { 553 if (regs->regs[0]) {
554 case ERESTART_RESTARTBLOCK: 554 switch(regs->regs[2]) {
555 case ERESTARTNOHAND: 555 case ERESTART_RESTARTBLOCK:
556 regs->regs[2] = EINTR; 556 case ERESTARTNOHAND:
557 break;
558 case ERESTARTSYS:
559 if (!(ka->sa.sa_flags & SA_RESTART)) {
560 regs->regs[2] = EINTR; 557 regs->regs[2] = EINTR;
561 break; 558 break;
559 case ERESTARTSYS:
560 if (!(ka->sa.sa_flags & SA_RESTART)) {
561 regs->regs[2] = EINTR;
562 break;
563 }
564 /* fallthrough */
565 case ERESTARTNOINTR:
566 regs->regs[7] = regs->regs[26];
567 regs->regs[2] = regs->regs[0];
568 regs->cp0_epc -= 4;
562 } 569 }
563 /* fallthrough */
564 case ERESTARTNOINTR: /* Userland will reload $v0. */
565 regs->regs[7] = regs->regs[26];
566 regs->cp0_epc -= 8;
567 }
568 570
569 regs->regs[0] = 0; /* Don't deal with this again. */ 571 regs->regs[0] = 0; /* Don't deal with this again. */
572 }
570 573
571 if (sig_uses_siginfo(ka)) 574 if (sig_uses_siginfo(ka))
572 ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, 575 ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
@@ -625,17 +628,13 @@ static void do_signal(struct pt_regs *regs)
625 return; 628 return;
626 } 629 }
627 630
628 /*
629 * Who's code doesn't conform to the restartable syscall convention
630 * dies here!!! The li instruction, a single machine instruction,
631 * must directly be followed by the syscall instruction.
632 */
633 if (regs->regs[0]) { 631 if (regs->regs[0]) {
634 if (regs->regs[2] == ERESTARTNOHAND || 632 if (regs->regs[2] == ERESTARTNOHAND ||
635 regs->regs[2] == ERESTARTSYS || 633 regs->regs[2] == ERESTARTSYS ||
636 regs->regs[2] == ERESTARTNOINTR) { 634 regs->regs[2] == ERESTARTNOINTR) {
635 regs->regs[2] = regs->regs[0];
637 regs->regs[7] = regs->regs[26]; 636 regs->regs[7] = regs->regs[26];
638 regs->cp0_epc -= 8; 637 regs->cp0_epc -= 4;
639 } 638 }
640 if (regs->regs[2] == ERESTART_RESTARTBLOCK) { 639 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
641 regs->regs[2] = current->thread.abi->restart; 640 regs->regs[2] = current->thread.abi->restart;