[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>
This commit is contained in:
Родитель
304416da86
Коммит
82ad93f4a0
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче