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

Commit e94c805f authored by Russell King's avatar Russell King
Browse files

Merge branch 'for-arm' of...

Merge branch 'for-arm' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal.git into for-linus

Conflicts:
	arch/arm/kernel/ptrace.c
parents ef0c1484 70b58d89
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
#define TIF_SYSCALL_TRACE	8
#define TIF_SYSCALL_AUDIT	9
#define TIF_SYSCALL_RESTARTSYS	10
#define TIF_POLLING_NRFLAG	16
#define TIF_USING_IWMMXT	17
#define TIF_MEMDIE		18	/* is terminating due to OOM killer */
@@ -162,16 +163,17 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
#define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
#define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
#define _TIF_SECCOMP		(1 << TIF_SECCOMP)
#define _TIF_SYSCALL_RESTARTSYS	(1 << TIF_SYSCALL_RESTARTSYS)

/* Checks for any syscall work in entry-common.S */
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
			   _TIF_SYSCALL_RESTARTSYS)

/*
 * Change these and you break ASM code in entry-common.S
 */
#define _TIF_WORK_MASK		0x000000ff
#define _TIF_WORK_MASK		(_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME)

#endif /* __KERNEL__ */
#endif /* __ASM_ARM_THREAD_INFO_H */
+6 −2
Original line number Diff line number Diff line
@@ -53,9 +53,13 @@ fast_work_pending:
work_pending:
	tst	r1, #_TIF_NEED_RESCHED
	bne	work_resched
	tst	r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
	beq	no_work_pending
	/*
	 * TIF_SIGPENDING or TIF_NOTIFY_RESUME must've been set if we got here
	 */
	ldr	r2, [sp, #S_PSR]
	mov	r0, sp				@ 'regs'
	tst	r2, #15				@ are we returning to user mode?
	bne	no_work_pending			@ no?  just leave, then...
	mov	r2, why				@ 'syscall'
	tst	r1, #_TIF_SIGPENDING		@ delivering a signal?
	movne	why, #0				@ prevent further restarts
+3 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/regset.h>
#include <linux/audit.h>
#include <linux/tracehook.h>
#include <linux/unistd.h>

#include <asm/pgtable.h>
#include <asm/traps.h>
@@ -917,6 +918,8 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
		audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0,
				    regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);

	if (why == 0 && test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS))
		scno = __NR_restart_syscall - __NR_SYSCALL_BASE;
	if (!test_thread_flag(TIF_SYSCALL_TRACE))
		return scno;

+18 −67
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@
 */
#define SWI_SYS_SIGRETURN	(0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
#define SWI_SYS_RT_SIGRETURN	(0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
#define SWI_SYS_RESTART		(0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)

/*
 * With EABI, the syscall number has to be loaded into r7.
@@ -49,18 +48,6 @@ const unsigned long sigreturn_codes[7] = {
	MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
};

/*
 * Either we support OABI only, or we have EABI with the OABI
 * compat layer enabled.  In the later case we don't know if
 * user space is EABI or not, and if not we must not clobber r7.
 * Always using the OABI syscall solves that issue and works for
 * all those cases.
 */
const unsigned long syscall_restart_code[2] = {
	SWI_SYS_RESTART,	/* swi	__NR_restart_syscall */
	0xe49df004,		/* ldr	pc, [sp], #4 */
};

/*
 * atomically swap in the new signal mask, and wait for a signal.
 */
@@ -91,10 +78,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *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))
		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
		    __get_user(mask, &act->sa_mask))
			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);
	}

@@ -103,10 +90,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
	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))
		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
			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;
@@ -610,15 +597,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
	siginfo_t info;
	int signr;

	/*
	 * We want the common case to go fast, which
	 * is why we may in certain cases get here from
	 * kernel mode. Just return without doing anything
	 * if so.
	 */
	if (!user_mode(regs))
		return;

	/*
	 * If we were from a system call, check for system call restarting...
	 */
@@ -635,18 +613,13 @@ static void do_signal(struct pt_regs *regs, int syscall)
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
		case -ERESTART_RESTARTBLOCK:
			regs->ARM_r0 = regs->ARM_ORIG_r0;
			regs->ARM_pc = restart_addr;
			break;
		case -ERESTART_RESTARTBLOCK:
			regs->ARM_r0 = -EINTR;
			break;
		}
	}

	if (try_to_freeze())
		goto no_signal;

	/*
	 * Get the signal to deliver.  When running under ptrace, at this
	 * point the debugger may change all our registers ...
@@ -661,12 +634,14 @@ static void do_signal(struct pt_regs *regs, int syscall)
		 * debugger has chosen to restart at a different PC.
		 */
		if (regs->ARM_pc == restart_addr) {
			if (retval == -ERESTARTNOHAND
			if (retval == -ERESTARTNOHAND ||
			    retval == -ERESTART_RESTARTBLOCK
			    || (retval == -ERESTARTSYS
				&& !(ka.sa.sa_flags & SA_RESTART))) {
				regs->ARM_r0 = -EINTR;
				regs->ARM_pc = continue_addr;
			}
			clear_thread_flag(TIF_SYSCALL_RESTARTSYS);
		}

		if (test_thread_flag(TIF_RESTORE_SIGMASK))
@@ -686,7 +661,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
		return;
	}

 no_signal:
	if (syscall) {
		/*
		 * Handle restarting a different system call.  As above,
@@ -694,38 +668,15 @@ static void do_signal(struct pt_regs *regs, int syscall)
		 * ignore the restart.
		 */
		if (retval == -ERESTART_RESTARTBLOCK
		    && regs->ARM_pc == continue_addr) {
			if (thumb_mode(regs)) {
				regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
				regs->ARM_pc -= 2;
			} else {
#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT)
				regs->ARM_r7 = __NR_restart_syscall;
				regs->ARM_pc -= 4;
#else
				u32 __user *usp;

				regs->ARM_sp -= 4;
				usp = (u32 __user *)regs->ARM_sp;

				if (put_user(regs->ARM_pc, usp) == 0) {
					regs->ARM_pc = KERN_RESTART_CODE;
				} else {
					regs->ARM_sp += 4;
					force_sigsegv(0, current);
				}
#endif
			}
		    && regs->ARM_pc == restart_addr)
			set_thread_flag(TIF_SYSCALL_RESTARTSYS);
	}

	/* If there's no signal to deliver, we just put the saved sigmask
	 * back.
	 */
		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
			clear_thread_flag(TIF_RESTORE_SIGMASK);
			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
		}
	}
	if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK))
		set_current_blocked(&current->saved_sigmask);
}

asmlinkage void
+0 −2
Original line number Diff line number Diff line
@@ -8,7 +8,5 @@
 * published by the Free Software Foundation.
 */
#define KERN_SIGRETURN_CODE	(CONFIG_VECTORS_BASE + 0x00000500)
#define KERN_RESTART_CODE	(KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))

extern const unsigned long sigreturn_codes[7];
extern const unsigned long syscall_restart_code[2];
Loading