powerpc: switch to generic sigaltstack
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
0aa0203fb4
commit
7cce246557
|
@ -144,6 +144,7 @@ config PPC
|
||||||
select HAVE_MOD_ARCH_SPECIFIC
|
select HAVE_MOD_ARCH_SPECIFIC
|
||||||
select MODULES_USE_ELF_RELA
|
select MODULES_USE_ELF_RELA
|
||||||
select CLONE_BACKWARDS
|
select CLONE_BACKWARDS
|
||||||
|
select GENERIC_SIGALTSTACK
|
||||||
|
|
||||||
config EARLY_PRINTK
|
config EARLY_PRINTK
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -22,9 +22,5 @@ asmlinkage long ppc64_personality(unsigned long personality);
|
||||||
asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
|
asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
|
||||||
asmlinkage time_t sys64_time(time_t __user * tloc);
|
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 /* __KERNEL__ */
|
||||||
#endif /* __ASM_POWERPC_SYSCALLS_H */
|
#endif /* __ASM_POWERPC_SYSCALLS_H */
|
||||||
|
|
|
@ -34,12 +34,6 @@ struct sigaction32 {
|
||||||
compat_sigset_t sa_mask; /* A 32 bit mask */
|
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 {
|
struct pt_regs32 {
|
||||||
unsigned int gpr[32];
|
unsigned int gpr[32];
|
||||||
unsigned int nip;
|
unsigned int nip;
|
||||||
|
@ -75,7 +69,7 @@ struct mcontext32 {
|
||||||
struct ucontext32 {
|
struct ucontext32 {
|
||||||
unsigned int uc_flags;
|
unsigned int uc_flags;
|
||||||
unsigned int uc_link;
|
unsigned int uc_link;
|
||||||
stack_32_t uc_stack;
|
compat_stack_t uc_stack;
|
||||||
int uc_pad[7];
|
int uc_pad[7];
|
||||||
compat_uptr_t uc_regs; /* points to uc_mcontext field */
|
compat_uptr_t uc_regs; /* points to uc_mcontext field */
|
||||||
compat_sigset_t uc_sigmask; /* mask last for extensibility */
|
compat_sigset_t uc_sigmask; /* mask last for extensibility */
|
||||||
|
|
|
@ -169,10 +169,3 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
|
||||||
tracehook_notify_resume(regs);
|
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]);
|
|
||||||
}
|
|
||||||
|
|
|
@ -67,6 +67,8 @@
|
||||||
#define mcontext mcontext32
|
#define mcontext mcontext32
|
||||||
#define ucontext ucontext32
|
#define ucontext ucontext32
|
||||||
|
|
||||||
|
#define __save_altstack __compat_save_altstack
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Userspace code may pass a ucontext which doesn't include VSX added
|
* Userspace code may pass a ucontext which doesn't include VSX added
|
||||||
* at the end. We need to check for this case.
|
* 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);
|
set_fs (old_fs);
|
||||||
return ret;
|
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 */
|
#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)
|
if (copy_siginfo_to_user(&rt_sf->info, info)
|
||||||
|| __put_user(0, &rt_sf->uc.uc_flags)
|
|| __put_user(0, &rt_sf->uc.uc_flags)
|
||||||
|| __put_user(0, &rt_sf->uc.uc_link)
|
|| __put_user(0, &rt_sf->uc.uc_link)
|
||||||
|| __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
|
|| __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1])
|
||||||
|| __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)
|
|
||||||
|| __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
|
|| __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
|
||||||
&rt_sf->uc.uc_regs)
|
&rt_sf->uc.uc_regs)
|
||||||
|| put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
|
|| 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
|
* change it. -- paulus
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
/*
|
if (compat_restore_altstack(&rt_sf->uc.uc_stack))
|
||||||
* We use the compat_sys_ version that does the 32/64 bits conversion
|
goto bad;
|
||||||
* 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);
|
|
||||||
#else
|
#else
|
||||||
do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
|
if (restore_altstack(&rt_sf->uc.uc_stack))
|
||||||
|
goto bad;
|
||||||
#endif
|
#endif
|
||||||
set_thread_flag(TIF_RESTOREALL);
|
set_thread_flag(TIF_RESTOREALL);
|
||||||
return 0;
|
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
|
* always done it up until now so it is probably better not to
|
||||||
* change it. -- paulus
|
* change it. -- paulus
|
||||||
*/
|
*/
|
||||||
do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
|
restore_altstack(&ctx->uc_stack);
|
||||||
|
|
||||||
set_thread_flag(TIF_RESTOREALL);
|
set_thread_flag(TIF_RESTOREALL);
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -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))
|
if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
||||||
/* do_sigaltstack expects a __user pointer and won't modify
|
if (restore_altstack(&uc->uc_stack))
|
||||||
* what's in there anyway
|
goto badframe;
|
||||||
*/
|
|
||||||
do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]);
|
|
||||||
|
|
||||||
set_thread_flag(TIF_RESTOREALL);
|
set_thread_flag(TIF_RESTOREALL);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -416,10 +414,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
|
||||||
/* Create the ucontext. */
|
/* Create the ucontext. */
|
||||||
err |= __put_user(0, &frame->uc.uc_flags);
|
err |= __put_user(0, &frame->uc.uc_flags);
|
||||||
err |= __put_user(0, &frame->uc.uc_link);
|
err |= __put_user(0, &frame->uc.uc_link);
|
||||||
err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
|
err |= __save_altstack(&frame->uc.uc_stack, regs->gpr[1]);
|
||||||
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 |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL,
|
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL,
|
||||||
(unsigned long)ka->sa.sa_handler, 1);
|
(unsigned long)ka->sa.sa_handler, 1);
|
||||||
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
|
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
|
||||||
|
|
Loading…
Reference in New Issue