diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-12-23 03:26:46 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-02-03 18:16:08 -0500 |
commit | 7cce246557bf379ea271d91f257ce248362cc12d (patch) | |
tree | a3c6c9c6f590990cbb1b3b6671b8c5e3fd1ff55a /arch/powerpc | |
parent | 0aa0203fb43f04714004b2c4ad33b858e240555d (diff) |
powerpc: switch to generic sigaltstack
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/syscalls.h | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/ppc32.h | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal.c | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 69 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 11 |
6 files changed, 13 insertions, 87 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 17903f1f356b..dd52babec7d7 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -144,6 +144,7 @@ config PPC | |||
144 | select HAVE_MOD_ARCH_SPECIFIC | 144 | select HAVE_MOD_ARCH_SPECIFIC |
145 | select MODULES_USE_ELF_RELA | 145 | select MODULES_USE_ELF_RELA |
146 | select CLONE_BACKWARDS | 146 | select CLONE_BACKWARDS |
147 | select GENERIC_SIGALTSTACK | ||
147 | 148 | ||
148 | config EARLY_PRINTK | 149 | config EARLY_PRINTK |
149 | bool | 150 | bool |
diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h index 6949c42ffac2..01d240ded0d5 100644 --- a/arch/powerpc/include/asm/syscalls.h +++ b/arch/powerpc/include/asm/syscalls.h | |||
@@ -22,9 +22,5 @@ asmlinkage long ppc64_personality(unsigned long personality); | |||
22 | asmlinkage int ppc_rtas(struct rtas_args __user *uargs); | 22 | asmlinkage int ppc_rtas(struct rtas_args __user *uargs); |
23 | asmlinkage time_t sys64_time(time_t __user * tloc); | 23 | asmlinkage time_t sys64_time(time_t __user * tloc); |
24 | 24 | ||
25 | asmlinkage long sys_sigaltstack(const stack_t __user *uss, | ||
26 | stack_t __user *uoss, unsigned long r5, unsigned long r6, | ||
27 | unsigned long r7, unsigned long r8, struct pt_regs *regs); | ||
28 | |||
29 | #endif /* __KERNEL__ */ | 25 | #endif /* __KERNEL__ */ |
30 | #endif /* __ASM_POWERPC_SYSCALLS_H */ | 26 | #endif /* __ASM_POWERPC_SYSCALLS_H */ |
diff --git a/arch/powerpc/kernel/ppc32.h b/arch/powerpc/kernel/ppc32.h index 02fb0ee26093..f6bee3e6f438 100644 --- a/arch/powerpc/kernel/ppc32.h +++ b/arch/powerpc/kernel/ppc32.h | |||
@@ -34,12 +34,6 @@ struct sigaction32 { | |||
34 | compat_sigset_t sa_mask; /* A 32 bit mask */ | 34 | compat_sigset_t sa_mask; /* A 32 bit mask */ |
35 | }; | 35 | }; |
36 | 36 | ||
37 | typedef struct sigaltstack_32 { | ||
38 | unsigned int ss_sp; | ||
39 | int ss_flags; | ||
40 | compat_size_t ss_size; | ||
41 | } stack_32_t; | ||
42 | |||
43 | struct pt_regs32 { | 37 | struct pt_regs32 { |
44 | unsigned int gpr[32]; | 38 | unsigned int gpr[32]; |
45 | unsigned int nip; | 39 | unsigned int nip; |
@@ -75,7 +69,7 @@ struct mcontext32 { | |||
75 | struct ucontext32 { | 69 | struct ucontext32 { |
76 | unsigned int uc_flags; | 70 | unsigned int uc_flags; |
77 | unsigned int uc_link; | 71 | unsigned int uc_link; |
78 | stack_32_t uc_stack; | 72 | compat_stack_t uc_stack; |
79 | int uc_pad[7]; | 73 | int uc_pad[7]; |
80 | compat_uptr_t uc_regs; /* points to uc_mcontext field */ | 74 | compat_uptr_t uc_regs; /* points to uc_mcontext field */ |
81 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 75 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 3b997118df50..fa99dc54965c 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
@@ -169,10 +169,3 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | |||
169 | tracehook_notify_resume(regs); | 169 | tracehook_notify_resume(regs); |
170 | } | 170 | } |
171 | } | 171 | } |
172 | |||
173 | long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | ||
174 | unsigned long r5, unsigned long r6, unsigned long r7, | ||
175 | unsigned long r8, struct pt_regs *regs) | ||
176 | { | ||
177 | return do_sigaltstack(uss, uoss, regs->gpr[1]); | ||
178 | } | ||
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 9ec3fed3caac..0ea248c893cb 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -67,6 +67,8 @@ | |||
67 | #define mcontext mcontext32 | 67 | #define mcontext mcontext32 |
68 | #define ucontext ucontext32 | 68 | #define ucontext ucontext32 |
69 | 69 | ||
70 | #define __save_altstack __compat_save_altstack | ||
71 | |||
70 | /* | 72 | /* |
71 | * Userspace code may pass a ucontext which doesn't include VSX added | 73 | * Userspace code may pass a ucontext which doesn't include VSX added |
72 | * at the end. We need to check for this case. | 74 | * at the end. We need to check for this case. |
@@ -763,55 +765,6 @@ long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo | |||
763 | set_fs (old_fs); | 765 | set_fs (old_fs); |
764 | return ret; | 766 | return ret; |
765 | } | 767 | } |
766 | /* | ||
767 | * Start Alternate signal stack support | ||
768 | * | ||
769 | * System Calls | ||
770 | * sigaltatck compat_sys_sigaltstack | ||
771 | */ | ||
772 | |||
773 | int compat_sys_sigaltstack(u32 __new, u32 __old, int r5, | ||
774 | int r6, int r7, int r8, struct pt_regs *regs) | ||
775 | { | ||
776 | stack_32_t __user * newstack = compat_ptr(__new); | ||
777 | stack_32_t __user * oldstack = compat_ptr(__old); | ||
778 | stack_t uss, uoss; | ||
779 | int ret; | ||
780 | mm_segment_t old_fs; | ||
781 | unsigned long sp; | ||
782 | compat_uptr_t ss_sp; | ||
783 | |||
784 | /* | ||
785 | * set sp to the user stack on entry to the system call | ||
786 | * the system call router sets R9 to the saved registers | ||
787 | */ | ||
788 | sp = regs->gpr[1]; | ||
789 | |||
790 | /* Put new stack info in local 64 bit stack struct */ | ||
791 | if (newstack) { | ||
792 | if (get_user(ss_sp, &newstack->ss_sp) || | ||
793 | __get_user(uss.ss_flags, &newstack->ss_flags) || | ||
794 | __get_user(uss.ss_size, &newstack->ss_size)) | ||
795 | return -EFAULT; | ||
796 | uss.ss_sp = compat_ptr(ss_sp); | ||
797 | } | ||
798 | |||
799 | old_fs = get_fs(); | ||
800 | set_fs(KERNEL_DS); | ||
801 | /* The __user pointer casts are valid because of the set_fs() */ | ||
802 | ret = do_sigaltstack( | ||
803 | newstack ? (stack_t __user *) &uss : NULL, | ||
804 | oldstack ? (stack_t __user *) &uoss : NULL, | ||
805 | sp); | ||
806 | set_fs(old_fs); | ||
807 | /* Copy the stack information to the user output buffer */ | ||
808 | if (!ret && oldstack && | ||
809 | (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) || | ||
810 | __put_user(uoss.ss_flags, &oldstack->ss_flags) || | ||
811 | __put_user(uoss.ss_size, &oldstack->ss_size))) | ||
812 | return -EFAULT; | ||
813 | return ret; | ||
814 | } | ||
815 | #endif /* CONFIG_PPC64 */ | 768 | #endif /* CONFIG_PPC64 */ |
816 | 769 | ||
817 | /* | 770 | /* |
@@ -838,10 +791,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
838 | if (copy_siginfo_to_user(&rt_sf->info, info) | 791 | if (copy_siginfo_to_user(&rt_sf->info, info) |
839 | || __put_user(0, &rt_sf->uc.uc_flags) | 792 | || __put_user(0, &rt_sf->uc.uc_flags) |
840 | || __put_user(0, &rt_sf->uc.uc_link) | 793 | || __put_user(0, &rt_sf->uc.uc_link) |
841 | || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) | 794 | || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1]) |
842 | || __put_user(sas_ss_flags(regs->gpr[1]), | ||
843 | &rt_sf->uc.uc_stack.ss_flags) | ||
844 | || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) | ||
845 | || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), | 795 | || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), |
846 | &rt_sf->uc.uc_regs) | 796 | &rt_sf->uc.uc_regs) |
847 | || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) | 797 | || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) |
@@ -1038,14 +988,11 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, | |||
1038 | * change it. -- paulus | 988 | * change it. -- paulus |
1039 | */ | 989 | */ |
1040 | #ifdef CONFIG_PPC64 | 990 | #ifdef CONFIG_PPC64 |
1041 | /* | 991 | if (compat_restore_altstack(&rt_sf->uc.uc_stack)) |
1042 | * We use the compat_sys_ version that does the 32/64 bits conversion | 992 | goto bad; |
1043 | * and takes userland pointer directly. What about error checking ? | ||
1044 | * nobody does any... | ||
1045 | */ | ||
1046 | compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); | ||
1047 | #else | 993 | #else |
1048 | do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); | 994 | if (restore_altstack(&rt_sf->uc.uc_stack)) |
995 | goto bad; | ||
1049 | #endif | 996 | #endif |
1050 | set_thread_flag(TIF_RESTOREALL); | 997 | set_thread_flag(TIF_RESTOREALL); |
1051 | return 0; | 998 | return 0; |
@@ -1161,7 +1108,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx, | |||
1161 | * always done it up until now so it is probably better not to | 1108 | * always done it up until now so it is probably better not to |
1162 | * change it. -- paulus | 1109 | * change it. -- paulus |
1163 | */ | 1110 | */ |
1164 | do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); | 1111 | restore_altstack(&ctx->uc_stack); |
1165 | 1112 | ||
1166 | set_thread_flag(TIF_RESTOREALL); | 1113 | set_thread_flag(TIF_RESTOREALL); |
1167 | out: | 1114 | out: |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 1ca045d44324..807b5b1535e9 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -368,10 +368,8 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, | |||
368 | if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext)) | 368 | if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext)) |
369 | goto badframe; | 369 | goto badframe; |
370 | 370 | ||
371 | /* do_sigaltstack expects a __user pointer and won't modify | 371 | if (restore_altstack(&uc->uc_stack)) |
372 | * what's in there anyway | 372 | goto badframe; |
373 | */ | ||
374 | do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]); | ||
375 | 373 | ||
376 | set_thread_flag(TIF_RESTOREALL); | 374 | set_thread_flag(TIF_RESTOREALL); |
377 | return 0; | 375 | return 0; |
@@ -416,10 +414,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, | |||
416 | /* Create the ucontext. */ | 414 | /* Create the ucontext. */ |
417 | err |= __put_user(0, &frame->uc.uc_flags); | 415 | err |= __put_user(0, &frame->uc.uc_flags); |
418 | err |= __put_user(0, &frame->uc.uc_link); | 416 | err |= __put_user(0, &frame->uc.uc_link); |
419 | err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); | 417 | err |= __save_altstack(&frame->uc.uc_stack, regs->gpr[1]); |
420 | err |= __put_user(sas_ss_flags(regs->gpr[1]), | ||
421 | &frame->uc.uc_stack.ss_flags); | ||
422 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); | ||
423 | err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL, | 418 | err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL, |
424 | (unsigned long)ka->sa.sa_handler, 1); | 419 | (unsigned long)ka->sa.sa_handler, 1); |
425 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 420 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |