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

Commit a7f8388e authored by Al Viro's avatar Al Viro Committed by Linus Torvalds
Browse files

m32r: fix rt_sigsuspend()



do_signal() should know about saved_mask for it to work...

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a850ea30
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -157,7 +157,6 @@ typedef struct sigaltstack {
#undef __HAVE_ARCH_SIG_BITOPS
#undef __HAVE_ARCH_SIG_BITOPS


struct pt_regs;
struct pt_regs;
extern int do_signal(struct pt_regs *regs, sigset_t *oldset);


#define ptrace_signal_deliver(regs, cookie)	do { } while (0)
#define ptrace_signal_deliver(regs, cookie)	do { } while (0)


+1 −0
Original line number Original line Diff line number Diff line
@@ -351,6 +351,7 @@
#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND


#define __IGNORE_lchown
#define __IGNORE_lchown
#define __IGNORE_setuid
#define __IGNORE_setuid
+1 −2
Original line number Original line Diff line number Diff line
@@ -235,8 +235,7 @@ work_resched:
work_notifysig:				; deal with pending signals and
work_notifysig:				; deal with pending signals and
					; notify-resume requests
					; notify-resume requests
	mv	r0, sp			; arg1 : struct pt_regs *regs
	mv	r0, sp			; arg1 : struct pt_regs *regs
	ldi	r1, #0			; arg2 : sigset_t *oldset
	ldi	r1, r9			; arg2 : __u32 thread_info_flags
	mv	r2, r9			; arg3 : __u32 thread_info_flags
	bl	do_notify_resume
	bl	do_notify_resume
	bra	restore_all
	bra	restore_all


+12 −36
Original line number Original line Diff line number Diff line
@@ -28,37 +28,6 @@


#define DEBUG_SIG 0
#define DEBUG_SIG 0


#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))

int do_signal(struct pt_regs *, sigset_t *);

asmlinkage int
sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
		  unsigned long r2, unsigned long r3, unsigned long r4,
		  unsigned long r5, unsigned long r6, struct pt_regs *regs)
{
	sigset_t newset;

	/* XXX: Don't preclude handling different sized sigset_t's.  */
	if (sigsetsize != sizeof(sigset_t))
		return -EINVAL;

	if (copy_from_user(&newset, unewset, sizeof(newset)))
		return -EFAULT;
	sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));

	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;
}

asmlinkage int
asmlinkage int
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
		unsigned long r2, unsigned long r3, unsigned long r4,
		unsigned long r2, unsigned long r3, unsigned long r4,
@@ -332,12 +301,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 * mistake.
 */
 */
int do_signal(struct pt_regs *regs, sigset_t *oldset)
static int do_signal(struct pt_regs *regs)
{
{
	siginfo_t info;
	siginfo_t info;
	int signr;
	int signr;
	struct k_sigaction ka;
	struct k_sigaction ka;
	unsigned short inst;
	unsigned short inst;
	sigset_t *oldset;


	/*
	/*
	 * We want the common case to go fast, which
	 * We want the common case to go fast, which
@@ -351,7 +321,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
	if (try_to_freeze()) 
	if (try_to_freeze()) 
		goto no_signal;
		goto no_signal;


	if (!oldset)
	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;
		oldset = &current->blocked;


	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -364,6 +336,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)


		/* Whee!  Actually deliver the signal.  */
		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, &ka, &info, oldset, regs);
		handle_signal(signr, &ka, &info, oldset, regs);
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		return 1;
		return 1;
	}
	}


@@ -391,6 +364,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
				regs->bpc -= 4;
				regs->bpc -= 4;
		}
		}
	}
	}
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
	return 0;
	return 0;
}
}


@@ -398,8 +375,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
 * notification of userspace execution resumption
 * notification of userspace execution resumption
 * - triggered by current->work.notify_resume
 * - triggered by current->work.notify_resume
 */
 */
void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
		      __u32 thread_info_flags)
{
{
	/* Pending single-step? */
	/* Pending single-step? */
	if (thread_info_flags & _TIF_SINGLESTEP)
	if (thread_info_flags & _TIF_SINGLESTEP)
@@ -407,7 +383,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,


	/* deal with pending signal delivery */
	/* deal with pending signal delivery */
	if (thread_info_flags & _TIF_SIGPENDING)
	if (thread_info_flags & _TIF_SIGPENDING)
		do_signal(regs,oldset);
		do_signal(regs);


	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
		clear_thread_flag(TIF_NOTIFY_RESUME);
		clear_thread_flag(TIF_NOTIFY_RESUME);