aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-12-23 03:26:46 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2013-02-03 18:16:08 -0500
commit7cce246557bf379ea271d91f257ce248362cc12d (patch)
treea3c6c9c6f590990cbb1b3b6671b8c5e3fd1ff55a /arch/powerpc
parent0aa0203fb43f04714004b2c4ad33b858e240555d (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/Kconfig1
-rw-r--r--arch/powerpc/include/asm/syscalls.h4
-rw-r--r--arch/powerpc/kernel/ppc32.h8
-rw-r--r--arch/powerpc/kernel/signal.c7
-rw-r--r--arch/powerpc/kernel/signal_32.c69
-rw-r--r--arch/powerpc/kernel/signal_64.c11
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
148config EARLY_PRINTK 149config 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);
22asmlinkage int ppc_rtas(struct rtas_args __user *uargs); 22asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
23asmlinkage time_t sys64_time(time_t __user * tloc); 23asmlinkage time_t sys64_time(time_t __user * tloc);
24 24
25asmlinkage 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
37typedef struct sigaltstack_32 {
38 unsigned int ss_sp;
39 int ss_flags;
40 compat_size_t ss_size;
41} stack_32_t;
42
43struct pt_regs32 { 37struct 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 {
75struct ucontext32 { 69struct 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
173long 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
773int 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));