aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/signal.c
diff options
context:
space:
mode:
authorSuresh Siddha <suresh.b.siddha@intel.com>2012-07-24 19:05:27 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2012-09-18 18:51:26 -0400
commit050902c011712ad4703038fa4489ec4edd87d396 (patch)
tree63a32b428111d5198ea668b9807976ae033ec96d /arch/x86/kernel/signal.c
parentae13b7b4e041eccf34fa4dd58581fe1441375578 (diff)
x86, signal: Cleanup ifdefs and is_ia32, is_x32
Use config_enabled() to cleanup the definitions of is_ia32/is_x32. Move the function prototypes to the header file to cleanup ifdefs, and move the x32_setup_rt_frame() code around. Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Link: http://lkml.kernel.org/r/1343171129-2747-2-git-send-email-suresh.b.siddha@intel.com Merged in compilation fix from, Link: http://lkml.kernel.org/r/1344544736.8326.17.camel@sbsiddha-desk.sc.intel.com Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel/signal.c')
-rw-r--r--arch/x86/kernel/signal.c196
1 files changed, 81 insertions, 115 deletions
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index b280908a376e..bed431a38162 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -209,24 +209,21 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
209 unsigned long sp = regs->sp; 209 unsigned long sp = regs->sp;
210 int onsigstack = on_sig_stack(sp); 210 int onsigstack = on_sig_stack(sp);
211 211
212#ifdef CONFIG_X86_64
213 /* redzone */ 212 /* redzone */
214 sp -= 128; 213 if (config_enabled(CONFIG_X86_64))
215#endif /* CONFIG_X86_64 */ 214 sp -= 128;
216 215
217 if (!onsigstack) { 216 if (!onsigstack) {
218 /* This is the X/Open sanctioned signal stack switching. */ 217 /* This is the X/Open sanctioned signal stack switching. */
219 if (ka->sa.sa_flags & SA_ONSTACK) { 218 if (ka->sa.sa_flags & SA_ONSTACK) {
220 if (current->sas_ss_size) 219 if (current->sas_ss_size)
221 sp = current->sas_ss_sp + current->sas_ss_size; 220 sp = current->sas_ss_sp + current->sas_ss_size;
222 } else { 221 } else if (config_enabled(CONFIG_X86_32) &&
223#ifdef CONFIG_X86_32 222 (regs->ss & 0xffff) != __USER_DS &&
224 /* This is the legacy signal stack switching. */ 223 !(ka->sa.sa_flags & SA_RESTORER) &&
225 if ((regs->ss & 0xffff) != __USER_DS && 224 ka->sa.sa_restorer) {
226 !(ka->sa.sa_flags & SA_RESTORER) && 225 /* This is the legacy signal stack switching. */
227 ka->sa.sa_restorer)
228 sp = (unsigned long) ka->sa.sa_restorer; 226 sp = (unsigned long) ka->sa.sa_restorer;
229#endif /* CONFIG_X86_32 */
230 } 227 }
231 } 228 }
232 229
@@ -474,6 +471,74 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
474} 471}
475#endif /* CONFIG_X86_32 */ 472#endif /* CONFIG_X86_32 */
476 473
474static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
475 siginfo_t *info, compat_sigset_t *set,
476 struct pt_regs *regs)
477{
478#ifdef CONFIG_X86_X32_ABI
479 struct rt_sigframe_x32 __user *frame;
480 void __user *restorer;
481 int err = 0;
482 void __user *fpstate = NULL;
483
484 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
485
486 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
487 return -EFAULT;
488
489 if (ka->sa.sa_flags & SA_SIGINFO) {
490 if (copy_siginfo_to_user32(&frame->info, info))
491 return -EFAULT;
492 }
493
494 put_user_try {
495 /* Create the ucontext. */
496 if (cpu_has_xsave)
497 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
498 else
499 put_user_ex(0, &frame->uc.uc_flags);
500 put_user_ex(0, &frame->uc.uc_link);
501 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
502 put_user_ex(sas_ss_flags(regs->sp),
503 &frame->uc.uc_stack.ss_flags);
504 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
505 put_user_ex(0, &frame->uc.uc__pad0);
506 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
507 regs, set->sig[0]);
508 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
509
510 if (ka->sa.sa_flags & SA_RESTORER) {
511 restorer = ka->sa.sa_restorer;
512 } else {
513 /* could use a vstub here */
514 restorer = NULL;
515 err |= -EFAULT;
516 }
517 put_user_ex(restorer, &frame->pretcode);
518 } put_user_catch(err);
519
520 if (err)
521 return -EFAULT;
522
523 /* Set up registers for signal handler */
524 regs->sp = (unsigned long) frame;
525 regs->ip = (unsigned long) ka->sa.sa_handler;
526
527 /* We use the x32 calling convention here... */
528 regs->di = sig;
529 regs->si = (unsigned long) &frame->info;
530 regs->dx = (unsigned long) &frame->uc;
531
532 loadsegment(ds, __USER_DS);
533 loadsegment(es, __USER_DS);
534
535 regs->cs = __USER_CS;
536 regs->ss = __USER_DS;
537#endif /* CONFIG_X86_X32_ABI */
538
539 return 0;
540}
541
477#ifdef CONFIG_X86_32 542#ifdef CONFIG_X86_32
478/* 543/*
479 * Atomically swap in the new signal mask, and wait for a signal. 544 * Atomically swap in the new signal mask, and wait for a signal.
@@ -612,55 +677,22 @@ static int signr_convert(int sig)
612 return sig; 677 return sig;
613} 678}
614 679
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 680static int
647setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 681setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
648 struct pt_regs *regs) 682 struct pt_regs *regs)
649{ 683{
650 int usig = signr_convert(sig); 684 int usig = signr_convert(sig);
651 sigset_t *set = sigmask_to_save(); 685 sigset_t *set = sigmask_to_save();
686 compat_sigset_t *cset = (compat_sigset_t *) set;
652 687
653 /* Set up the stack frame */ 688 /* Set up the stack frame */
654 if (is_ia32) { 689 if (is_ia32_frame()) {
655 if (ka->sa.sa_flags & SA_SIGINFO) 690 if (ka->sa.sa_flags & SA_SIGINFO)
656 return ia32_setup_rt_frame(usig, ka, info, set, regs); 691 return ia32_setup_rt_frame(usig, ka, info, cset, regs);
657 else 692 else
658 return ia32_setup_frame(usig, ka, set, regs); 693 return ia32_setup_frame(usig, ka, cset, regs);
659#ifdef CONFIG_X86_X32_ABI 694 } else if (is_x32_frame()) {
660 } else if (is_x32) { 695 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 { 696 } else {
665 return __setup_rt_frame(sig, ka, info, set, regs); 697 return __setup_rt_frame(sig, ka, info, set, regs);
666 } 698 }
@@ -824,72 +856,6 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
824} 856}
825 857
826#ifdef CONFIG_X86_X32_ABI 858#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) 859asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs)
894{ 860{
895 struct rt_sigframe_x32 __user *frame; 861 struct rt_sigframe_x32 __user *frame;