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

Commit e5fa2d06 authored by Hiroshi Shimamoto's avatar Hiroshi Shimamoto Committed by Ingo Molnar
Browse files

x86: signal: unify signal_{32|64}.c, prepare



Impact: cleanup

Add #ifdef directive for 32-bit only code.

Signed-off-by: default avatarHiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent bfeb91a9
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
/*
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *  Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs
 *
 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
 *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
 *  2000-2002   x86-64 support by Andi Kleen
 */

#include <linux/sched.h>
@@ -481,6 +483,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
#endif /* CONFIG_X86_32 */

#ifdef CONFIG_X86_32
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
@@ -535,6 +538,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,

	return ret;
}
#endif /* CONFIG_X86_32 */

#ifdef CONFIG_X86_32
asmlinkage int sys_sigaltstack(unsigned long bx)
@@ -561,6 +565,7 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
/*
 * Do a signal return; undo the signal stack.
 */
#ifdef CONFIG_X86_32
asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
{
	struct sigframe __user *frame;
@@ -603,6 +608,7 @@ asmlinkage unsigned long sys_sigreturn(unsigned long __unused)

	return 0;
}
#endif /* CONFIG_X86_32 */

static long do_rt_sigreturn(struct pt_regs *regs)
{
+115 −1
Original line number Diff line number Diff line
@@ -54,12 +54,24 @@
	err |= __get_user(regs->x, &sc->x);	\
}

#define COPY_SEG(seg)		{			\
		unsigned short tmp;			\
		err |= __get_user(tmp, &sc->seg);	\
		regs->seg = tmp;			\
}

#define COPY_SEG_CPL3(seg)	{			\
		unsigned short tmp;			\
		err |= __get_user(tmp, &sc->seg);	\
		regs->seg = tmp | 3;			\
}

#define GET_SEG(seg)		{			\
		unsigned short tmp;			\
		err |= __get_user(tmp, &sc->seg);	\
		loadsegment(seg, tmp);			\
}

static int
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
		   unsigned long *pax)
@@ -471,6 +483,63 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
#endif /* CONFIG_X86_32 */

#ifdef CONFIG_X86_32
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int
sys_sigsuspend(int history0, int history1, old_sigset_t mask)
{
	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	current->saved_sigmask = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_restore_sigmask();

	return -ERESTARTNOHAND;
}

asmlinkage int
sys_sigaction(int sig, const struct old_sigaction __user *act,
	      struct old_sigaction __user *oact)
{
	struct k_sigaction new_ka, old_ka;
	int ret;

	if (act) {
		old_sigset_t mask;

		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
			return -EFAULT;

		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
		__get_user(mask, &act->sa_mask);
		siginitset(&new_ka.sa.sa_mask, mask);
	}

	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

	if (!ret && oact) {
		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
			return -EFAULT;

		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
	}

	return ret;
}
#endif /* CONFIG_X86_32 */

#ifdef CONFIG_X86_32
asmlinkage int sys_sigaltstack(unsigned long bx)
{
@@ -496,6 +565,51 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
/*
 * Do a signal return; undo the signal stack.
 */
#ifdef CONFIG_X86_32
asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
{
	struct sigframe __user *frame;
	struct pt_regs *regs;
	unsigned long ax;
	sigset_t set;

	regs = (struct pt_regs *) &__unused;
	frame = (struct sigframe __user *)(regs->sp - 8);

	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
		goto badframe;
	if (__get_user(set.sig[0], &frame->sc.oldmask) || (_NSIG_WORDS > 1
		&& __copy_from_user(&set.sig[1], &frame->extramask,
				    sizeof(frame->extramask))))
		goto badframe;

	sigdelsetmask(&set, ~_BLOCKABLE);
	spin_lock_irq(&current->sighand->siglock);
	current->blocked = set;
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	if (restore_sigcontext(regs, &frame->sc, &ax))
		goto badframe;
	return ax;

badframe:
	if (show_unhandled_signals && printk_ratelimit()) {
		printk("%s%s[%d] bad frame in sigreturn frame:"
			"%p ip:%lx sp:%lx oeax:%lx",
		    task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
		    current->comm, task_pid_nr(current), frame, regs->ip,
		    regs->sp, regs->orig_ax);
		print_vma_addr(" in ", regs->ip);
		printk(KERN_CONT "\n");
	}

	force_sig(SIGSEGV, current);

	return 0;
}
#endif /* CONFIG_X86_32 */

static long do_rt_sigreturn(struct pt_regs *regs)
{
	struct rt_sigframe __user *frame;
@@ -542,7 +656,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
#endif /* CONFIG_X86_32 */

/*
 * OK, we're invoking a handler
 * OK, we're invoking a handler:
 */
static int signr_convert(int sig)
{