diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-02-18 22:47:26 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-02-21 16:58:22 +0000 |
commit | 82ad93f4a002294820e9a5e6f84beef2222a54b7 (patch) | |
tree | 24423db4db76379224daeb5716fbe8b3885cd234 /arch/mips/kernel | |
parent | 304416da860b8cd548e61ee7038f852418008a85 (diff) |
[MIPS] N32: Fix N32 rt_sigtimedwait and rt_sigsuspend breakage.
Originally found through an oops in the Gentoo N32 userland build; patch
based on original patch by Daniel Jacobwitz.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/linux32.c | 19 | ||||
-rw-r--r-- | arch/mips/kernel/scall64-n32.S | 4 | ||||
-rw-r--r-- | arch/mips/kernel/signal_n32.c | 33 |
3 files changed, 35 insertions, 21 deletions
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 60353f5acc4..9996b6e8458 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -1450,25 +1450,6 @@ sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *ti return sys_timer_create(clock, p, timer_id); } -asmlinkage long -sysn32_rt_sigtimedwait(const sigset_t __user *uthese, - siginfo_t __user *uinfo, - const struct compat_timespec __user *uts32, - size_t sigsetsize) -{ - struct timespec __user *uts = NULL; - - if (uts32) { - struct timespec ts; - uts = compat_alloc_user_space(sizeof(struct timespec)); - if (get_user(ts.tv_sec, &uts32->tv_sec) || - get_user(ts.tv_nsec, &uts32->tv_nsec) || - copy_to_user (uts, &ts, sizeof (ts))) - return -EFAULT; - } - return sys_rt_sigtimedwait(uthese, uinfo, uts, sigsetsize); -} - save_static_function(sys32_clone); __attribute_used__ noinline static int _sys32_clone(nabi_no_regargs struct pt_regs regs) diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index bc4980cefc8..d87b5446fa1 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -245,9 +245,9 @@ EXPORT(sysn32_call_table) PTR sys_capget PTR sys_capset PTR sys32_rt_sigpending /* 6125 */ - PTR sysn32_rt_sigtimedwait + PTR compat_sys_rt_sigtimedwait PTR sys_rt_sigqueueinfo - PTR sys32_rt_sigsuspend + PTR sysn32_rt_sigsuspend PTR sys32_sigaltstack PTR compat_sys_utime /* 6130 */ PTR sys_mknod diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 5a3776096f0..3e168c08a3a 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -81,6 +81,39 @@ struct rt_sigframe_n32 { #endif }; +extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat); + +save_static_function(sysn32_rt_sigsuspend); +__attribute_used__ noinline static int +_sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) +{ + compat_sigset_t __user *unewset, uset; + size_t sigsetsize; + sigset_t newset; + + /* XXX Don't preclude handling different sized sigset_t's. */ + sigsetsize = regs.regs[5]; + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + unewset = (compat_sigset_t __user *) regs.regs[4]; + if (copy_from_user(&uset, unewset, sizeof(uset))) + return -EFAULT; + sigset_from_compat (&newset, &uset); + sigdelsetmask(&newset, ~_BLOCKABLE); + + spin_lock_irq(¤t->sighand->siglock); + current->saved_sigmask = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; +} + save_static_function(sysn32_rt_sigreturn); __attribute_used__ noinline static void _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) |