Commit ea536ad4 authored by Al Viro's avatar Al Viro

mips: switch to generic sigaltstack

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent c6489c14
...@@ -41,6 +41,7 @@ config MIPS ...@@ -41,6 +41,7 @@ config MIPS
select HAVE_MOD_ARCH_SPECIFIC select HAVE_MOD_ARCH_SPECIFIC
select MODULES_USE_ELF_REL if MODULES select MODULES_USE_ELF_REL if MODULES
select MODULES_USE_ELF_RELA if MODULES && 64BIT select MODULES_USE_ELF_RELA if MODULES && 64BIT
select GENERIC_SIGALTSTACK
menu "Machine selection" menu "Machine selection"
......
...@@ -288,6 +288,14 @@ struct compat_shmid64_ds { ...@@ -288,6 +288,14 @@ struct compat_shmid64_ds {
compat_ulong_t __unused2; compat_ulong_t __unused2;
}; };
/* MIPS has unusual order of fields in stack_t */
typedef struct compat_sigaltstack {
compat_uptr_t ss_sp;
compat_size_t ss_size;
int ss_flags;
} compat_stack_t;
#define compat_sigaltstack compat_sigaltstack
static inline int is_compat_task(void) static inline int is_compat_task(void)
{ {
return test_thread_flag(TIF_32BIT_ADDR); return test_thread_flag(TIF_32BIT_ADDR);
......
...@@ -233,7 +233,7 @@ EXPORT(sysn32_call_table) ...@@ -233,7 +233,7 @@ EXPORT(sysn32_call_table)
PTR compat_sys_rt_sigtimedwait PTR compat_sys_rt_sigtimedwait
PTR sys_32_rt_sigqueueinfo PTR sys_32_rt_sigqueueinfo
PTR sysn32_rt_sigsuspend PTR sysn32_rt_sigsuspend
PTR sys32_sigaltstack PTR compat_sys_sigaltstack
PTR compat_sys_utime /* 6130 */ PTR compat_sys_utime /* 6130 */
PTR sys_mknod PTR sys_mknod
PTR sys_32_personality PTR sys_32_personality
......
...@@ -398,7 +398,7 @@ sys_call_table: ...@@ -398,7 +398,7 @@ sys_call_table:
PTR sys_getcwd PTR sys_getcwd
PTR sys_capget PTR sys_capget
PTR sys_capset /* 4205 */ PTR sys_capset /* 4205 */
PTR sys32_sigaltstack PTR compat_sys_sigaltstack
PTR sys_32_sendfile PTR sys_32_sendfile
PTR sys_ni_syscall PTR sys_ni_syscall
PTR sys_ni_syscall PTR sys_ni_syscall
......
...@@ -313,15 +313,6 @@ SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act, ...@@ -313,15 +313,6 @@ SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act,
} }
#endif #endif
asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
{
const stack_t __user *uss = (const stack_t __user *) regs.regs[4];
stack_t __user *uoss = (stack_t __user *) regs.regs[5];
unsigned long usp = regs.regs[29];
return do_sigaltstack(uss, uoss, usp);
}
#ifdef CONFIG_TRAD_SIGNALS #ifdef CONFIG_TRAD_SIGNALS
asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs) asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
{ {
...@@ -378,9 +369,8 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) ...@@ -378,9 +369,8 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
else if (sig) else if (sig)
force_sig(sig, current); force_sig(sig, current);
/* It is more difficult to avoid calling this function than to if (restore_altstack(&frame->rs_uc.uc_stack))
call it and ignore errors. */ goto badframe;
do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs.regs[29]);
/* /*
* Don't let your children do this ... * Don't let your children do this ...
...@@ -457,12 +447,7 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka, ...@@ -457,12 +447,7 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
/* Create the ucontext. */ /* Create the ucontext. */
err |= __put_user(0, &frame->rs_uc.uc_flags); err |= __put_user(0, &frame->rs_uc.uc_flags);
err |= __put_user(NULL, &frame->rs_uc.uc_link); err |= __put_user(NULL, &frame->rs_uc.uc_link);
err |= __put_user((void __user *)current->sas_ss_sp, err |= __save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
&frame->rs_uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->regs[29]),
&frame->rs_uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size,
&frame->rs_uc.uc_stack.ss_size);
err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
......
...@@ -61,17 +61,10 @@ struct sigaction32 { ...@@ -61,17 +61,10 @@ struct sigaction32 {
compat_sigset_t sa_mask; compat_sigset_t sa_mask;
}; };
/* IRIX compatible stack_t */
typedef struct sigaltstack32 {
s32 ss_sp;
compat_size_t ss_size;
int ss_flags;
} stack32_t;
struct ucontext32 { struct ucontext32 {
u32 uc_flags; u32 uc_flags;
s32 uc_link; s32 uc_link;
stack32_t uc_stack; compat_stack_t uc_stack;
struct sigcontext32 uc_mcontext; struct sigcontext32 uc_mcontext;
compat_sigset_t uc_sigmask; /* mask last for extensibility */ compat_sigset_t uc_sigmask; /* mask last for extensibility */
}; };
...@@ -350,45 +343,6 @@ SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act, ...@@ -350,45 +343,6 @@ SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
return ret; return ret;
} }
asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
{
const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
unsigned long usp = regs.regs[29];
stack_t kss, koss;
int ret, err = 0;
mm_segment_t old_fs = get_fs();
s32 sp;
if (uss) {
if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
return -EFAULT;
err |= __get_user(sp, &uss->ss_sp);
kss.ss_sp = (void __user *) (long) sp;
err |= __get_user(kss.ss_size, &uss->ss_size);
err |= __get_user(kss.ss_flags, &uss->ss_flags);
if (err)
return -EFAULT;
}
set_fs(KERNEL_DS);
ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
uoss ? (stack_t __user *)&koss : NULL, usp);
set_fs(old_fs);
if (!ret && uoss) {
if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
return -EFAULT;
sp = (int) (unsigned long) koss.ss_sp;
err |= __put_user(sp, &uoss->ss_sp);
err |= __put_user(koss.ss_size, &uoss->ss_size);
err |= __put_user(koss.ss_flags, &uoss->ss_flags);
if (err)
return -EFAULT;
}
return ret;
}
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
{ {
int err; int err;
...@@ -490,10 +444,7 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs) ...@@ -490,10 +444,7 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
{ {
struct rt_sigframe32 __user *frame; struct rt_sigframe32 __user *frame;
mm_segment_t old_fs;
sigset_t set; sigset_t set;
stack_t st;
s32 sp;
int sig; int sig;
frame = (struct rt_sigframe32 __user *) regs.regs[29]; frame = (struct rt_sigframe32 __user *) regs.regs[29];
...@@ -510,22 +461,9 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) ...@@ -510,22 +461,9 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
else if (sig) else if (sig)
force_sig(sig, current); force_sig(sig, current);
/* The ucontext contains a stack32_t, so we must convert! */ if (compat_restore_altstack(&frame->rs_uc.uc_stack))
if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
goto badframe;
st.ss_sp = (void __user *)(long) sp;
if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
goto badframe;
if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
goto badframe; goto badframe;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
old_fs = get_fs();
set_fs(KERNEL_DS);
do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
set_fs(old_fs);
/* /*
* Don't let your children do this ... * Don't let your children do this ...
*/ */
...@@ -590,7 +528,6 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka, ...@@ -590,7 +528,6 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
{ {
struct rt_sigframe32 __user *frame; struct rt_sigframe32 __user *frame;
int err = 0; int err = 0;
s32 sp;
frame = get_sigframe(ka, regs, sizeof(*frame)); frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
...@@ -602,13 +539,7 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka, ...@@ -602,13 +539,7 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
/* Create the ucontext. */ /* Create the ucontext. */
err |= __put_user(0, &frame->rs_uc.uc_flags); err |= __put_user(0, &frame->rs_uc.uc_flags);
err |= __put_user(0, &frame->rs_uc.uc_link); err |= __put_user(0, &frame->rs_uc.uc_link);
sp = (int) (long) current->sas_ss_sp; err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
err |= __put_user(sp,
&frame->rs_uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->regs[29]),
&frame->rs_uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size,
&frame->rs_uc.uc_stack.ss_size);
err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext); err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set); err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
......
...@@ -50,18 +50,10 @@ ...@@ -50,18 +50,10 @@
extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *); extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
/* IRIX compatible stack_t */
typedef struct sigaltstack32 {
s32 ss_sp;
compat_size_t ss_size;
int ss_flags;
} stack32_t;
struct ucontextn32 { struct ucontextn32 {
u32 uc_flags; u32 uc_flags;
s32 uc_link; s32 uc_link;
stack32_t uc_stack; compat_stack_t uc_stack;
struct sigcontext uc_mcontext; struct sigcontext uc_mcontext;
compat_sigset_t uc_sigmask; /* mask last for extensibility */ compat_sigset_t uc_sigmask; /* mask last for extensibility */
}; };
...@@ -97,10 +89,7 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) ...@@ -97,10 +89,7 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
{ {
struct rt_sigframe_n32 __user *frame; struct rt_sigframe_n32 __user *frame;
mm_segment_t old_fs;
sigset_t set; sigset_t set;
stack_t st;
s32 sp;
int sig; int sig;
frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
...@@ -117,22 +106,8 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) ...@@ -117,22 +106,8 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
else if (sig) else if (sig)
force_sig(sig, current); force_sig(sig, current);
/* The ucontext contains a stack32_t, so we must convert! */ if (compat_restore_altstack(&frame->rs_uc.uc_stack))
if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
goto badframe;
st.ss_sp = (void __user *)(long) sp;
if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
goto badframe; goto badframe;
if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
goto badframe;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
old_fs = get_fs();
set_fs(KERNEL_DS);
do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
set_fs(old_fs);
/* /*
* Don't let your children do this ... * Don't let your children do this ...
...@@ -153,7 +128,6 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka, ...@@ -153,7 +128,6 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
{ {
struct rt_sigframe_n32 __user *frame; struct rt_sigframe_n32 __user *frame;
int err = 0; int err = 0;
s32 sp;
frame = get_sigframe(ka, regs, sizeof(*frame)); frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
...@@ -165,13 +139,7 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka, ...@@ -165,13 +139,7 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
/* Create the ucontext. */ /* Create the ucontext. */
err |= __put_user(0, &frame->rs_uc.uc_flags); err |= __put_user(0, &frame->rs_uc.uc_flags);
err |= __put_user(0, &frame->rs_uc.uc_link); err |= __put_user(0, &frame->rs_uc.uc_link);
sp = (int) (long) current->sas_ss_sp; err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
err |= __put_user(sp,
&frame->rs_uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->regs[29]),
&frame->rs_uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size,
&frame->rs_uc.uc_stack.ss_size);
err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set); err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment