From 529911ad7225e33fc82deb0612c43369afec02ba Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 23 Dec 2012 03:26:46 -0500 Subject: [PATCH] --- yaml --- r: 356724 b: refs/heads/master c: 7cce246557bf379ea271d91f257ce248362cc12d h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/parisc/Kconfig | 5 - trunk/arch/parisc/kernel/entry.S | 38 ++++++ trunk/arch/parisc/kernel/signal.c | 19 ++- trunk/arch/parisc/kernel/signal32.c | 142 ++++++++++++++++++++++ trunk/arch/parisc/kernel/signal32.h | 23 ++++ trunk/arch/parisc/kernel/sys32.h | 12 ++ trunk/arch/parisc/kernel/sys_parisc32.c | 12 ++ trunk/arch/parisc/kernel/syscall_table.S | 10 +- trunk/arch/powerpc/Kconfig | 1 + trunk/arch/powerpc/include/asm/syscalls.h | 4 - trunk/arch/powerpc/kernel/ppc32.h | 8 +- trunk/arch/powerpc/kernel/signal.c | 7 -- trunk/arch/powerpc/kernel/signal_32.c | 69 ++--------- trunk/arch/powerpc/kernel/signal_64.c | 11 +- 15 files changed, 261 insertions(+), 102 deletions(-) diff --git a/[refs] b/[refs] index 94d692d9a9ac..9f15ba908808 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b0f95824f2e91fb0df59fd63ddd6b36a94c05699 +refs/heads/master: 7cce246557bf379ea271d91f257ce248362cc12d diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index 2bd407ffaebf..b77feffbadea 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -23,11 +23,6 @@ config PARISC select HAVE_MOD_ARCH_SPECIFIC select MODULES_USE_ELF_RELA select CLONE_BACKWARDS - select GENERIC_SIGALTSTACK - select GENERIC_COMPAT_RT_SIGACTION - select GENERIC_COMPAT_RT_SIGQUEUEINFO - select GENERIC_COMPAT_RT_SIGPROCMASK - select GENERIC_COMPAT_RT_SIGPENDING help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index 240d153daec3..bfb44247d7a7 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -1748,6 +1748,44 @@ ENTRY(sys_rt_sigreturn_wrapper) LDREG PT_GR28(%r1),%r28 /* reload original r28 for syscall_exit */ ENDPROC(sys_rt_sigreturn_wrapper) +ENTRY(sys_sigaltstack_wrapper) + /* Get the user stack pointer */ + LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 + ldo TASK_REGS(%r1),%r24 /* get pt regs */ + LDREG TASK_PT_GR30(%r24),%r24 + STREG %r2, -RP_OFFSET(%r30) +#ifdef CONFIG_64BIT + ldo FRAME_SIZE(%r30), %r30 + BL do_sigaltstack,%r2 + ldo -16(%r30),%r29 /* Reference param save area */ +#else + BL do_sigaltstack,%r2 + ldo FRAME_SIZE(%r30), %r30 +#endif + + ldo -FRAME_SIZE(%r30), %r30 + LDREG -RP_OFFSET(%r30), %r2 + bv %r0(%r2) + nop +ENDPROC(sys_sigaltstack_wrapper) + +#ifdef CONFIG_64BIT +ENTRY(sys32_sigaltstack_wrapper) + /* Get the user stack pointer */ + LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24 + LDREG TASK_PT_GR30(%r24),%r24 + STREG %r2, -RP_OFFSET(%r30) + ldo FRAME_SIZE(%r30), %r30 + BL do_sigaltstack32,%r2 + ldo -16(%r30),%r29 /* Reference param save area */ + + ldo -FRAME_SIZE(%r30), %r30 + LDREG -RP_OFFSET(%r30), %r2 + bv %r0(%r2) + nop +ENDPROC(sys32_sigaltstack_wrapper) +#endif + ENTRY(syscall_exit) /* NOTE: HP-UX syscalls also come through here * after hpux_syscall_exit fixes up return diff --git a/trunk/arch/parisc/kernel/signal.c b/trunk/arch/parisc/kernel/signal.c index 64d315f6d2a4..537996955998 100644 --- a/trunk/arch/parisc/kernel/signal.c +++ b/trunk/arch/parisc/kernel/signal.c @@ -143,7 +143,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) goto give_sigsegv; DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", usp, &compat_frame->uc.uc_stack); - if (compat_restore_altstack(&compat_frame->uc.uc_stack)) + if (do_sigaltstack32(&compat_frame->uc.uc_stack, NULL, usp) == -EFAULT) goto give_sigsegv; } else #endif @@ -154,7 +154,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) goto give_sigsegv; DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", usp, &frame->uc.uc_stack); - if (restore_altstack(&frame->uc.uc_stack)) + if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT) goto give_sigsegv; } @@ -260,7 +260,15 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, if (is_compat_task()) { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); err |= copy_siginfo_to_user32(&compat_frame->info, info); - err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]); + DBG(1,"SETUP_RT_FRAME: 1\n"); + compat_val = (compat_int_t)current->sas_ss_sp; + err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp); + DBG(1,"SETUP_RT_FRAME: 2\n"); + compat_val = (compat_int_t)current->sas_ss_size; + err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_size); + DBG(1,"SETUP_RT_FRAME: 3\n"); + compat_val = sas_ss_flags(regs->gr[30]); + err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_flags); DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc); DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext); err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, @@ -272,7 +280,10 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info); err |= copy_siginfo_to_user(&frame->info, info); - err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]); + err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= __put_user(sas_ss_flags(regs->gr[30]), + &frame->uc.uc_stack.ss_flags); DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc); DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext); err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall); diff --git a/trunk/arch/parisc/kernel/signal32.c b/trunk/arch/parisc/kernel/signal32.c index 33eca1b04926..5dede04f2f3e 100644 --- a/trunk/arch/parisc/kernel/signal32.c +++ b/trunk/arch/parisc/kernel/signal32.c @@ -60,6 +60,129 @@ sigset_64to32(compat_sigset_t *s32, sigset_t *s64) s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL; } +static int +put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) +{ + compat_sigset_t s; + + if (sz != sizeof *set) + return -EINVAL; + sigset_64to32(&s, set); + + return copy_to_user(up, &s, sizeof s); +} + +static int +get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) +{ + compat_sigset_t s; + int r; + + if (sz != sizeof *set) + return -EINVAL; + + if ((r = copy_from_user(&s, up, sz)) == 0) { + sigset_32to64(set, &s); + } + + return r; +} + +int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset, + unsigned int sigsetsize) +{ + sigset_t old_set, new_set; + int ret; + + if (set && get_sigset32(set, &new_set, sigsetsize)) + return -EFAULT; + + KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL, + oset ? (sigset_t __user *)&old_set : NULL, sigsetsize); + + if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize)) + return -EFAULT; + + return ret; +} + + +int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize) +{ + int ret; + sigset_t set; + + KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize); + + if (!ret && put_sigset32(uset, &set, sigsetsize)) + return -EFAULT; + + return ret; +} + +long +sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact, + size_t sigsetsize) +{ + struct k_sigaction32 new_sa32, old_sa32; + struct k_sigaction new_sa, old_sa; + int ret = -EINVAL; + + if (act) { + if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa)) + return -EFAULT; + new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler; + new_sa.sa.sa_flags = new_sa32.sa.sa_flags; + sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask); + } + + ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL); + + if (!ret && oact) { + sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask); + old_sa32.sa.sa_flags = old_sa.sa.sa_flags; + old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler; + if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa)) + return -EFAULT; + } + return ret; +} + +int +do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp) +{ + compat_stack_t ss32, oss32; + stack_t ss, oss; + stack_t *ssp = NULL, *ossp = NULL; + int ret; + + if (uss32) { + if (copy_from_user(&ss32, uss32, sizeof ss32)) + return -EFAULT; + + ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp; + ss.ss_flags = ss32.ss_flags; + ss.ss_size = ss32.ss_size; + + ssp = &ss; + } + + if (uoss32) + ossp = &oss; + + KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp); + + if (!ret && uoss32) { + oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp; + oss32.ss_flags = oss.ss_flags; + oss32.ss_size = oss.ss_size; + if (copy_to_user(uoss32, &oss32, sizeof *uoss32)) + return -EFAULT; + } + + return ret; +} + long restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, struct pt_regs *regs) @@ -376,3 +499,22 @@ copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from) } return err; } + +asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig, + struct compat_siginfo __user *uinfo) +{ + siginfo_t info; + + if (copy_siginfo_from_user32(&info, uinfo)) + return -EFAULT; + + /* Not even root can pretend to send signals from the kernel. + Nor can they impersonate a kill(), which adds source info. */ + if (info.si_code >= 0) + return -EPERM; + info.si_signo = sig; + + /* POSIX.1b doesn't mention process groups. */ + return kill_proc_info(sig, &info, pid); +} + diff --git a/trunk/arch/parisc/kernel/signal32.h b/trunk/arch/parisc/kernel/signal32.h index 72ab41a51f32..08a88b5349a2 100644 --- a/trunk/arch/parisc/kernel/signal32.h +++ b/trunk/arch/parisc/kernel/signal32.h @@ -21,6 +21,23 @@ #include +typedef compat_uptr_t compat_sighandler_t; + +typedef struct compat_sigaltstack { + compat_uptr_t ss_sp; + compat_int_t ss_flags; + compat_size_t ss_size; +} compat_stack_t; + +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +struct compat_sigaction { + compat_sighandler_t sa_handler; + compat_uint_t sa_flags; + compat_sigset_t sa_mask; /* mask last for extensibility */ +}; + /* 32-bit ucontext as seen from an 64-bit kernel */ struct compat_ucontext { compat_uint_t uc_flags; @@ -34,6 +51,10 @@ struct compat_ucontext { /* ELF32 signal handling */ +struct k_sigaction32 { + struct compat_sigaction sa; +}; + int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); @@ -81,6 +102,8 @@ struct compat_rt_sigframe { void sigset_32to64(sigset_t *s64, compat_sigset_t *s32); void sigset_64to32(compat_sigset_t *s32, sigset_t *s64); +int do_sigaltstack32 (const compat_stack_t __user *uss32, + compat_stack_t __user *uoss32, unsigned long sp); long restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user *rf, struct pt_regs *regs); diff --git a/trunk/arch/parisc/kernel/sys32.h b/trunk/arch/parisc/kernel/sys32.h index 60dd470f39f8..06c2090cfaba 100644 --- a/trunk/arch/parisc/kernel/sys32.h +++ b/trunk/arch/parisc/kernel/sys32.h @@ -33,4 +33,16 @@ set_fs (old_fs); \ } +#ifdef CONFIG_COMPAT + +typedef __u32 __sighandler_t32; + +struct sigaction32 { + __sighandler_t32 sa_handler; + unsigned int sa_flags; + compat_sigset_t sa_mask; /* mask last for extensibility */ +}; + +#endif + #endif diff --git a/trunk/arch/parisc/kernel/sys_parisc32.c b/trunk/arch/parisc/kernel/sys_parisc32.c index 9b6a376cb12b..9cfdaa19ab63 100644 --- a/trunk/arch/parisc/kernel/sys_parisc32.c +++ b/trunk/arch/parisc/kernel/sys_parisc32.c @@ -61,6 +61,18 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23, return -ENOSYS; } +asmlinkage long sys32_sched_rr_get_interval(pid_t pid, + struct compat_timespec __user *interval) +{ + struct timespec t; + int ret; + + KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, (struct timespec __user *)&t); + if (put_compat_timespec(&t, interval)) + return -EFAULT; + return ret; +} + struct msgbuf32 { int mtype; char mtext[1]; diff --git a/trunk/arch/parisc/kernel/syscall_table.S b/trunk/arch/parisc/kernel/syscall_table.S index dd52c23c0dcd..54d950b067b7 100644 --- a/trunk/arch/parisc/kernel/syscall_table.S +++ b/trunk/arch/parisc/kernel/syscall_table.S @@ -250,12 +250,12 @@ /* These 2 would've worked if someone had defined struct timespec * carefully, like timeval for example (which is about the same). * Unfortunately it contains a long :-( */ - ENTRY_COMP(sched_rr_get_interval) + ENTRY_DIFF(sched_rr_get_interval) ENTRY_COMP(nanosleep) ENTRY_SAME(mremap) ENTRY_SAME(setresuid) ENTRY_SAME(getresuid) /* 165 */ - ENTRY_COMP(sigaltstack) + ENTRY_DIFF(sigaltstack_wrapper) ENTRY_SAME(ni_syscall) /* query_module */ ENTRY_SAME(poll) /* structs contain pointers and an in_addr... */ @@ -265,9 +265,9 @@ ENTRY_SAME(prctl) /* signals need a careful review */ ENTRY_SAME(rt_sigreturn_wrapper) - ENTRY_COMP(rt_sigaction) - ENTRY_COMP(rt_sigprocmask) /* 175 */ - ENTRY_COMP(rt_sigpending) + ENTRY_DIFF(rt_sigaction) + ENTRY_DIFF(rt_sigprocmask) /* 175 */ + ENTRY_DIFF(rt_sigpending) ENTRY_COMP(rt_sigtimedwait) /* even though the struct siginfo_t is different, it appears like * all the paths use values which should be same wide and narrow. diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 17903f1f356b..dd52babec7d7 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -144,6 +144,7 @@ config PPC select HAVE_MOD_ARCH_SPECIFIC select MODULES_USE_ELF_RELA select CLONE_BACKWARDS + select GENERIC_SIGALTSTACK config EARLY_PRINTK bool diff --git a/trunk/arch/powerpc/include/asm/syscalls.h b/trunk/arch/powerpc/include/asm/syscalls.h index 6949c42ffac2..01d240ded0d5 100644 --- a/trunk/arch/powerpc/include/asm/syscalls.h +++ b/trunk/arch/powerpc/include/asm/syscalls.h @@ -22,9 +22,5 @@ asmlinkage long ppc64_personality(unsigned long personality); asmlinkage int ppc_rtas(struct rtas_args __user *uargs); asmlinkage time_t sys64_time(time_t __user * tloc); -asmlinkage long sys_sigaltstack(const stack_t __user *uss, - stack_t __user *uoss, unsigned long r5, unsigned long r6, - unsigned long r7, unsigned long r8, struct pt_regs *regs); - #endif /* __KERNEL__ */ #endif /* __ASM_POWERPC_SYSCALLS_H */ diff --git a/trunk/arch/powerpc/kernel/ppc32.h b/trunk/arch/powerpc/kernel/ppc32.h index 02fb0ee26093..f6bee3e6f438 100644 --- a/trunk/arch/powerpc/kernel/ppc32.h +++ b/trunk/arch/powerpc/kernel/ppc32.h @@ -34,12 +34,6 @@ struct sigaction32 { compat_sigset_t sa_mask; /* A 32 bit mask */ }; -typedef struct sigaltstack_32 { - unsigned int ss_sp; - int ss_flags; - compat_size_t ss_size; -} stack_32_t; - struct pt_regs32 { unsigned int gpr[32]; unsigned int nip; @@ -75,7 +69,7 @@ struct mcontext32 { struct ucontext32 { unsigned int uc_flags; unsigned int uc_link; - stack_32_t uc_stack; + compat_stack_t uc_stack; int uc_pad[7]; compat_uptr_t uc_regs; /* points to uc_mcontext field */ compat_sigset_t uc_sigmask; /* mask last for extensibility */ diff --git a/trunk/arch/powerpc/kernel/signal.c b/trunk/arch/powerpc/kernel/signal.c index 3b997118df50..fa99dc54965c 100644 --- a/trunk/arch/powerpc/kernel/signal.c +++ b/trunk/arch/powerpc/kernel/signal.c @@ -169,10 +169,3 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) tracehook_notify_resume(regs); } } - -long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, - unsigned long r5, unsigned long r6, unsigned long r7, - unsigned long r8, struct pt_regs *regs) -{ - return do_sigaltstack(uss, uoss, regs->gpr[1]); -} diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index 9ec3fed3caac..0ea248c893cb 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -67,6 +67,8 @@ #define mcontext mcontext32 #define ucontext ucontext32 +#define __save_altstack __compat_save_altstack + /* * Userspace code may pass a ucontext which doesn't include VSX added * 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 set_fs (old_fs); return ret; } -/* - * Start Alternate signal stack support - * - * System Calls - * sigaltatck compat_sys_sigaltstack - */ - -int compat_sys_sigaltstack(u32 __new, u32 __old, int r5, - int r6, int r7, int r8, struct pt_regs *regs) -{ - stack_32_t __user * newstack = compat_ptr(__new); - stack_32_t __user * oldstack = compat_ptr(__old); - stack_t uss, uoss; - int ret; - mm_segment_t old_fs; - unsigned long sp; - compat_uptr_t ss_sp; - - /* - * set sp to the user stack on entry to the system call - * the system call router sets R9 to the saved registers - */ - sp = regs->gpr[1]; - - /* Put new stack info in local 64 bit stack struct */ - if (newstack) { - if (get_user(ss_sp, &newstack->ss_sp) || - __get_user(uss.ss_flags, &newstack->ss_flags) || - __get_user(uss.ss_size, &newstack->ss_size)) - return -EFAULT; - uss.ss_sp = compat_ptr(ss_sp); - } - - old_fs = get_fs(); - set_fs(KERNEL_DS); - /* The __user pointer casts are valid because of the set_fs() */ - ret = do_sigaltstack( - newstack ? (stack_t __user *) &uss : NULL, - oldstack ? (stack_t __user *) &uoss : NULL, - sp); - set_fs(old_fs); - /* Copy the stack information to the user output buffer */ - if (!ret && oldstack && - (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) || - __put_user(uoss.ss_flags, &oldstack->ss_flags) || - __put_user(uoss.ss_size, &oldstack->ss_size))) - return -EFAULT; - return ret; -} #endif /* CONFIG_PPC64 */ /* @@ -838,10 +791,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, if (copy_siginfo_to_user(&rt_sf->info, info) || __put_user(0, &rt_sf->uc.uc_flags) || __put_user(0, &rt_sf->uc.uc_link) - || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) - || __put_user(sas_ss_flags(regs->gpr[1]), - &rt_sf->uc.uc_stack.ss_flags) - || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) + || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1]) || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), &rt_sf->uc.uc_regs) || 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, * change it. -- paulus */ #ifdef CONFIG_PPC64 - /* - * We use the compat_sys_ version that does the 32/64 bits conversion - * and takes userland pointer directly. What about error checking ? - * nobody does any... - */ - compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); + if (compat_restore_altstack(&rt_sf->uc.uc_stack)) + goto bad; #else - do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); + if (restore_altstack(&rt_sf->uc.uc_stack)) + goto bad; #endif set_thread_flag(TIF_RESTOREALL); return 0; @@ -1161,7 +1108,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx, * always done it up until now so it is probably better not to * change it. -- paulus */ - do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); + restore_altstack(&ctx->uc_stack); set_thread_flag(TIF_RESTOREALL); out: diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index 1ca045d44324..807b5b1535e9 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -368,10 +368,8 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext)) goto badframe; - /* do_sigaltstack expects a __user pointer and won't modify - * what's in there anyway - */ - do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]); + if (restore_altstack(&uc->uc_stack)) + goto badframe; set_thread_flag(TIF_RESTOREALL); return 0; @@ -416,10 +414,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); err |= __put_user(0, &frame->uc.uc_link); - err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(regs->gpr[1]), - &frame->uc.uc_stack.ss_flags); - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= __save_altstack(&frame->uc.uc_stack, regs->gpr[1]); err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL, (unsigned long)ka->sa.sa_handler, 1); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));