diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2012-07-24 19:05:27 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-09-18 18:51:26 -0400 |
commit | 050902c011712ad4703038fa4489ec4edd87d396 (patch) | |
tree | 63a32b428111d5198ea668b9807976ae033ec96d /arch/x86/kernel/signal.c | |
parent | ae13b7b4e041eccf34fa4dd58581fe1441375578 (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.c | 196 |
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 | ||
474 | static 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 | |||
632 | static 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 | |||
639 | int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | ||
640 | sigset_t *set, struct pt_regs *regs); | ||
641 | int ia32_setup_frame(int sig, struct k_sigaction *ka, | ||
642 | sigset_t *set, struct pt_regs *regs); | ||
643 | |||
644 | #endif /* CONFIG_X86_32 */ | ||
645 | |||
646 | static int | 680 | static int |
647 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 681 | setup_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 |
827 | static 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 | |||
893 | asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs) | 859 | asmlinkage 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; |