Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82ad93f4 authored by Ralf Baechle's avatar Ralf Baechle
Browse files

[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: default avatarRalf Baechle <ralf@linux-mips.org>
parent 304416da
Loading
Loading
Loading
Loading
+0 −19
Original line number Diff line number Diff line
@@ -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)
+2 −2
Original line number Diff line number Diff line
@@ -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
+33 −0
Original line number Diff line number Diff line
@@ -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(&current->sighand->siglock);
	current->saved_sigmask = current->blocked;
	current->blocked = newset;
        recalc_sigpending();
	spin_unlock_irq(&current->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)