aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/signal_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/signal_64.c')
-rw-r--r--arch/sh/kernel/signal_64.c61
1 files changed, 26 insertions, 35 deletions
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 0663a0ee6021..5a9f1f10ebf4 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -101,7 +101,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
101 if (try_to_freeze()) 101 if (try_to_freeze())
102 goto no_signal; 102 goto no_signal;
103 103
104 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 104 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
105 oldset = &current->saved_sigmask; 105 oldset = &current->saved_sigmask;
106 else if (!oldset) 106 else if (!oldset)
107 oldset = &current->blocked; 107 oldset = &current->blocked;
@@ -115,12 +115,12 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
115 /* 115 /*
116 * If a signal was successfully delivered, the 116 * If a signal was successfully delivered, the
117 * saved sigmask is in its frame, and we can 117 * saved sigmask is in its frame, and we can
118 * clear the TIF_RESTORE_SIGMASK flag. 118 * clear the TS_RESTORE_SIGMASK flag.
119 */ 119 */
120 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 120 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
121 clear_thread_flag(TIF_RESTORE_SIGMASK);
122 121
123 tracehook_signal_handler(signr, &info, &ka, regs, 0); 122 tracehook_signal_handler(signr, &info, &ka, regs,
123 test_thread_flag(TIF_SINGLESTEP));
124 return 1; 124 return 1;
125 } 125 }
126 } 126 }
@@ -146,8 +146,8 @@ no_signal:
146 } 146 }
147 147
148 /* No signal to deliver -- put the saved sigmask back */ 148 /* No signal to deliver -- put the saved sigmask back */
149 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 149 if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
150 clear_thread_flag(TIF_RESTORE_SIGMASK); 150 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
151 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 151 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
152 } 152 }
153 153
@@ -176,6 +176,7 @@ sys_sigsuspend(old_sigset_t mask,
176 while (1) { 176 while (1) {
177 current->state = TASK_INTERRUPTIBLE; 177 current->state = TASK_INTERRUPTIBLE;
178 schedule(); 178 schedule();
179 set_restore_sigmask();
179 regs->pc += 4; /* because sys_sigreturn decrements the pc */ 180 regs->pc += 4; /* because sys_sigreturn decrements the pc */
180 if (do_signal(regs, &saveset)) { 181 if (do_signal(regs, &saveset)) {
181 /* pc now points at signal handler. Need to decrement 182 /* pc now points at signal handler. Need to decrement
@@ -296,7 +297,7 @@ restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
296 regs->sr |= SR_FD; 297 regs->sr |= SR_FD;
297 } 298 }
298 299
299 err |= __copy_from_user(&current->thread.fpu.hard, &sc->sc_fpregs[0], 300 err |= __copy_from_user(&current->thread.xstate->hardfpu, &sc->sc_fpregs[0],
300 (sizeof(long long) * 32) + (sizeof(int) * 1)); 301 (sizeof(long long) * 32) + (sizeof(int) * 1));
301 302
302 return err; 303 return err;
@@ -315,13 +316,13 @@ setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
315 316
316 if (current == last_task_used_math) { 317 if (current == last_task_used_math) {
317 enable_fpu(); 318 enable_fpu();
318 save_fpu(current, regs); 319 save_fpu(current);
319 disable_fpu(); 320 disable_fpu();
320 last_task_used_math = NULL; 321 last_task_used_math = NULL;
321 regs->sr |= SR_FD; 322 regs->sr |= SR_FD;
322 } 323 }
323 324
324 err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.fpu.hard, 325 err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.xstate->hardfpu,
325 (sizeof(long long) * 32) + (sizeof(int) * 1)); 326 (sizeof(long long) * 32) + (sizeof(int) * 1));
326 clear_used_math(); 327 clear_used_math();
327 328
@@ -561,13 +562,11 @@ static int setup_frame(int sig, struct k_sigaction *ka,
561 /* Set up to return from userspace. If provided, use a stub 562 /* Set up to return from userspace. If provided, use a stub
562 already in userspace. */ 563 already in userspace. */
563 if (ka->sa.sa_flags & SA_RESTORER) { 564 if (ka->sa.sa_flags & SA_RESTORER) {
564 DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
565
566 /* 565 /*
567 * On SH5 all edited pointers are subject to NEFF 566 * On SH5 all edited pointers are subject to NEFF
568 */ 567 */
569 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? 568 DEREF_REG_PR = neff_sign_extend((unsigned long)
570 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; 569 ka->sa.sa_restorer | 0x1);
571 } else { 570 } else {
572 /* 571 /*
573 * Different approach on SH5. 572 * Different approach on SH5.
@@ -580,9 +579,8 @@ static int setup_frame(int sig, struct k_sigaction *ka,
580 * . being code, linker turns ShMedia bit on, always 579 * . being code, linker turns ShMedia bit on, always
581 * dereference index -1. 580 * dereference index -1.
582 */ 581 */
583 DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; 582 DEREF_REG_PR = neff_sign_extend((unsigned long)
584 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? 583 frame->retcode | 0x01);
585 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
586 584
587 if (__copy_to_user(frame->retcode, 585 if (__copy_to_user(frame->retcode,
588 (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0) 586 (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
@@ -596,9 +594,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
596 * Set up registers for signal handler. 594 * Set up registers for signal handler.
597 * All edited pointers are subject to NEFF. 595 * All edited pointers are subject to NEFF.
598 */ 596 */
599 regs->regs[REG_SP] = (unsigned long) frame; 597 regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
600 regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
601 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
602 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ 598 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
603 599
604 /* FIXME: 600 /* FIXME:
@@ -613,8 +609,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
613 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc; 609 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
614 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc; 610 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
615 611
616 regs->pc = (unsigned long) ka->sa.sa_handler; 612 regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
617 regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
618 613
619 set_fs(USER_DS); 614 set_fs(USER_DS);
620 615
@@ -676,13 +671,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
676 /* Set up to return from userspace. If provided, use a stub 671 /* Set up to return from userspace. If provided, use a stub
677 already in userspace. */ 672 already in userspace. */
678 if (ka->sa.sa_flags & SA_RESTORER) { 673 if (ka->sa.sa_flags & SA_RESTORER) {
679 DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
680
681 /* 674 /*
682 * On SH5 all edited pointers are subject to NEFF 675 * On SH5 all edited pointers are subject to NEFF
683 */ 676 */
684 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? 677 DEREF_REG_PR = neff_sign_extend((unsigned long)
685 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; 678 ka->sa.sa_restorer | 0x1);
686 } else { 679 } else {
687 /* 680 /*
688 * Different approach on SH5. 681 * Different approach on SH5.
@@ -695,15 +688,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
695 * . being code, linker turns ShMedia bit on, always 688 * . being code, linker turns ShMedia bit on, always
696 * dereference index -1. 689 * dereference index -1.
697 */ 690 */
698 691 DEREF_REG_PR = neff_sign_extend((unsigned long)
699 DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; 692 frame->retcode | 0x01);
700 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
701 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
702 693
703 if (__copy_to_user(frame->retcode, 694 if (__copy_to_user(frame->retcode,
704 (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0) 695 (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
705 goto give_sigsegv; 696 goto give_sigsegv;
706 697
698 /* Cohere the trampoline with the I-cache. */
707 flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15); 699 flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
708 } 700 }
709 701
@@ -711,14 +703,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
711 * Set up registers for signal handler. 703 * Set up registers for signal handler.
712 * All edited pointers are subject to NEFF. 704 * All edited pointers are subject to NEFF.
713 */ 705 */
714 regs->regs[REG_SP] = (unsigned long) frame; 706 regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
715 regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
716 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
717 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ 707 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
718 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info; 708 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
719 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext; 709 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
720 regs->pc = (unsigned long) ka->sa.sa_handler; 710 regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
721 regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
722 711
723 set_fs(USER_DS); 712 set_fs(USER_DS);
724 713
@@ -772,5 +761,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info
772 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 761 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
773 clear_thread_flag(TIF_NOTIFY_RESUME); 762 clear_thread_flag(TIF_NOTIFY_RESUME);
774 tracehook_notify_resume(regs); 763 tracehook_notify_resume(regs);
764 if (current->replacement_session_keyring)
765 key_replace_session_keyring();
775 } 766 }
776} 767}