aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/signal.c')
-rw-r--r--arch/x86/kernel/signal.c215
1 files changed, 93 insertions, 122 deletions
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index b280908a376e..3160c26db5e7 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -114,7 +114,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
114 regs->orig_ax = -1; /* disable syscall checks */ 114 regs->orig_ax = -1; /* disable syscall checks */
115 115
116 get_user_ex(buf, &sc->fpstate); 116 get_user_ex(buf, &sc->fpstate);
117 err |= restore_i387_xstate(buf); 117 err |= restore_xstate_sig(buf, config_enabled(CONFIG_X86_32));
118 118
119 get_user_ex(*pax, &sc->ax); 119 get_user_ex(*pax, &sc->ax);
120 } get_user_catch(err); 120 } get_user_catch(err);
@@ -206,35 +206,32 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
206 void __user **fpstate) 206 void __user **fpstate)
207{ 207{
208 /* Default to using normal stack */ 208 /* Default to using normal stack */
209 unsigned long math_size = 0;
209 unsigned long sp = regs->sp; 210 unsigned long sp = regs->sp;
211 unsigned long buf_fx = 0;
210 int onsigstack = on_sig_stack(sp); 212 int onsigstack = on_sig_stack(sp);
211 213
212#ifdef CONFIG_X86_64
213 /* redzone */ 214 /* redzone */
214 sp -= 128; 215 if (config_enabled(CONFIG_X86_64))
215#endif /* CONFIG_X86_64 */ 216 sp -= 128;
216 217
217 if (!onsigstack) { 218 if (!onsigstack) {
218 /* This is the X/Open sanctioned signal stack switching. */ 219 /* This is the X/Open sanctioned signal stack switching. */
219 if (ka->sa.sa_flags & SA_ONSTACK) { 220 if (ka->sa.sa_flags & SA_ONSTACK) {
220 if (current->sas_ss_size) 221 if (current->sas_ss_size)
221 sp = current->sas_ss_sp + current->sas_ss_size; 222 sp = current->sas_ss_sp + current->sas_ss_size;
222 } else { 223 } else if (config_enabled(CONFIG_X86_32) &&
223#ifdef CONFIG_X86_32 224 (regs->ss & 0xffff) != __USER_DS &&
224 /* This is the legacy signal stack switching. */ 225 !(ka->sa.sa_flags & SA_RESTORER) &&
225 if ((regs->ss & 0xffff) != __USER_DS && 226 ka->sa.sa_restorer) {
226 !(ka->sa.sa_flags & SA_RESTORER) && 227 /* This is the legacy signal stack switching. */
227 ka->sa.sa_restorer)
228 sp = (unsigned long) ka->sa.sa_restorer; 228 sp = (unsigned long) ka->sa.sa_restorer;
229#endif /* CONFIG_X86_32 */
230 } 229 }
231 } 230 }
232 231
233 if (used_math()) { 232 if (used_math()) {
234 sp -= sig_xstate_size; 233 sp = alloc_mathframe(sp, config_enabled(CONFIG_X86_32),
235#ifdef CONFIG_X86_64 234 &buf_fx, &math_size);
236 sp = round_down(sp, 64);
237#endif /* CONFIG_X86_64 */
238 *fpstate = (void __user *)sp; 235 *fpstate = (void __user *)sp;
239 } 236 }
240 237
@@ -247,8 +244,9 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
247 if (onsigstack && !likely(on_sig_stack(sp))) 244 if (onsigstack && !likely(on_sig_stack(sp)))
248 return (void __user *)-1L; 245 return (void __user *)-1L;
249 246
250 /* save i387 state */ 247 /* save i387 and extended state */
251 if (used_math() && save_i387_xstate(*fpstate) < 0) 248 if (used_math() &&
249 save_xstate_sig(*fpstate, (void __user *)buf_fx, math_size) < 0)
252 return (void __user *)-1L; 250 return (void __user *)-1L;
253 251
254 return (void __user *)sp; 252 return (void __user *)sp;
@@ -474,6 +472,74 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
474} 472}
475#endif /* CONFIG_X86_32 */ 473#endif /* CONFIG_X86_32 */
476 474
475static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
476 siginfo_t *info, compat_sigset_t *set,
477 struct pt_regs *regs)
478{
479#ifdef CONFIG_X86_X32_ABI
480 struct rt_sigframe_x32 __user *frame;
481 void __user *restorer;
482 int err = 0;
483 void __user *fpstate = NULL;
484
485 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
486
487 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
488 return -EFAULT;
489
490 if (ka->sa.sa_flags & SA_SIGINFO) {
491 if (copy_siginfo_to_user32(&frame->info, info))
492 return -EFAULT;
493 }
494
495 put_user_try {
496 /* Create the ucontext. */
497 if (cpu_has_xsave)
498 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
499 else
500 put_user_ex(0, &frame->uc.uc_flags);
501 put_user_ex(0, &frame->uc.uc_link);
502 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
503 put_user_ex(sas_ss_flags(regs->sp),
504 &frame->uc.uc_stack.ss_flags);
505 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
506 put_user_ex(0, &frame->uc.uc__pad0);
507 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
508 regs, set->sig[0]);
509 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
510
511 if (ka->sa.sa_flags & SA_RESTORER) {
512 restorer = ka->sa.sa_restorer;
513 } else {
514 /* could use a vstub here */
515 restorer = NULL;
516 err |= -EFAULT;
517 }
518 put_user_ex(restorer, &frame->pretcode);
519 } put_user_catch(err);
520
521 if (err)
522 return -EFAULT;
523
524 /* Set up registers for signal handler */
525 regs->sp = (unsigned long) frame;
526 regs->ip = (unsigned long) ka->sa.sa_handler;
527
528 /* We use the x32 calling convention here... */
529 regs->di = sig;
530 regs->si = (unsigned long) &frame->info;
531 regs->dx = (unsigned long) &frame->uc;
532
533 loadsegment(ds, __USER_DS);
534 loadsegment(es, __USER_DS);
535
536 regs->cs = __USER_CS;
537 regs->ss = __USER_DS;
538#endif /* CONFIG_X86_X32_ABI */
539
540 return 0;
541}
542
477#ifdef CONFIG_X86_32 543#ifdef CONFIG_X86_32
478/* 544/*
479 * Atomically swap in the new signal mask, and wait for a signal. 545 * Atomically swap in the new signal mask, and wait for a signal.
@@ -612,55 +678,22 @@ static int signr_convert(int sig)
612 return sig; 678 return sig;
613} 679}
614 680
615#ifdef CONFIG_X86_32
616
617#define is_ia32 1
618#define ia32_setup_frame __setup_frame
619#define ia32_setup_rt_frame __setup_rt_frame
620
621#else /* !CONFIG_X86_32 */
622
623#ifdef CONFIG_IA32_EMULATION
624#define is_ia32 test_thread_flag(TIF_IA32)
625#else /* !CONFIG_IA32_EMULATION */
626#define is_ia32 0
627#endif /* CONFIG_IA32_EMULATION */
628
629#ifdef CONFIG_X86_X32_ABI
630#define is_x32 test_thread_flag(TIF_X32)
631
632static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
633 siginfo_t *info, compat_sigset_t *set,
634 struct pt_regs *regs);
635#else /* !CONFIG_X86_X32_ABI */
636#define is_x32 0
637#endif /* CONFIG_X86_X32_ABI */
638
639int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
640 sigset_t *set, struct pt_regs *regs);
641int ia32_setup_frame(int sig, struct k_sigaction *ka,
642 sigset_t *set, struct pt_regs *regs);
643
644#endif /* CONFIG_X86_32 */
645
646static int 681static int
647setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 682setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
648 struct pt_regs *regs) 683 struct pt_regs *regs)
649{ 684{
650 int usig = signr_convert(sig); 685 int usig = signr_convert(sig);
651 sigset_t *set = sigmask_to_save(); 686 sigset_t *set = sigmask_to_save();
687 compat_sigset_t *cset = (compat_sigset_t *) set;
652 688
653 /* Set up the stack frame */ 689 /* Set up the stack frame */
654 if (is_ia32) { 690 if (is_ia32_frame()) {
655 if (ka->sa.sa_flags & SA_SIGINFO) 691 if (ka->sa.sa_flags & SA_SIGINFO)
656 return ia32_setup_rt_frame(usig, ka, info, set, regs); 692 return ia32_setup_rt_frame(usig, ka, info, cset, regs);
657 else 693 else
658 return ia32_setup_frame(usig, ka, set, regs); 694 return ia32_setup_frame(usig, ka, cset, regs);
659#ifdef CONFIG_X86_X32_ABI 695 } else if (is_x32_frame()) {
660 } else if (is_x32) { 696 return x32_setup_rt_frame(usig, ka, info, cset, regs);
661 return x32_setup_rt_frame(usig, ka, info,
662 (compat_sigset_t *)set, regs);
663#endif
664 } else { 697 } else {
665 return __setup_rt_frame(sig, ka, info, set, regs); 698 return __setup_rt_frame(sig, ka, info, set, regs);
666 } 699 }
@@ -779,6 +812,8 @@ static void do_signal(struct pt_regs *regs)
779void 812void
780do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) 813do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
781{ 814{
815 rcu_user_exit();
816
782#ifdef CONFIG_X86_MCE 817#ifdef CONFIG_X86_MCE
783 /* notify userspace of pending MCEs */ 818 /* notify userspace of pending MCEs */
784 if (thread_info_flags & _TIF_MCE_NOTIFY) 819 if (thread_info_flags & _TIF_MCE_NOTIFY)
@@ -804,6 +839,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
804#ifdef CONFIG_X86_32 839#ifdef CONFIG_X86_32
805 clear_thread_flag(TIF_IRET); 840 clear_thread_flag(TIF_IRET);
806#endif /* CONFIG_X86_32 */ 841#endif /* CONFIG_X86_32 */
842
843 rcu_user_enter();
807} 844}
808 845
809void signal_fault(struct pt_regs *regs, void __user *frame, char *where) 846void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
@@ -824,72 +861,6 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
824} 861}
825 862
826#ifdef CONFIG_X86_X32_ABI 863#ifdef CONFIG_X86_X32_ABI
827static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
828 siginfo_t *info, compat_sigset_t *set,
829 struct pt_regs *regs)
830{
831 struct rt_sigframe_x32 __user *frame;
832 void __user *restorer;
833 int err = 0;
834 void __user *fpstate = NULL;
835
836 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
837
838 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
839 return -EFAULT;
840
841 if (ka->sa.sa_flags & SA_SIGINFO) {
842 if (copy_siginfo_to_user32(&frame->info, info))
843 return -EFAULT;
844 }
845
846 put_user_try {
847 /* Create the ucontext. */
848 if (cpu_has_xsave)
849 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
850 else
851 put_user_ex(0, &frame->uc.uc_flags);
852 put_user_ex(0, &frame->uc.uc_link);
853 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
854 put_user_ex(sas_ss_flags(regs->sp),
855 &frame->uc.uc_stack.ss_flags);
856 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
857 put_user_ex(0, &frame->uc.uc__pad0);
858 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
859 regs, set->sig[0]);
860 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
861
862 if (ka->sa.sa_flags & SA_RESTORER) {
863 restorer = ka->sa.sa_restorer;
864 } else {
865 /* could use a vstub here */
866 restorer = NULL;
867 err |= -EFAULT;
868 }
869 put_user_ex(restorer, &frame->pretcode);
870 } put_user_catch(err);
871
872 if (err)
873 return -EFAULT;
874
875 /* Set up registers for signal handler */
876 regs->sp = (unsigned long) frame;
877 regs->ip = (unsigned long) ka->sa.sa_handler;
878
879 /* We use the x32 calling convention here... */
880 regs->di = sig;
881 regs->si = (unsigned long) &frame->info;
882 regs->dx = (unsigned long) &frame->uc;
883
884 loadsegment(ds, __USER_DS);
885 loadsegment(es, __USER_DS);
886
887 regs->cs = __USER_CS;
888 regs->ss = __USER_DS;
889
890 return 0;
891}
892
893asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs) 864asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs)
894{ 865{
895 struct rt_sigframe_x32 __user *frame; 866 struct rt_sigframe_x32 __user *frame;