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

Commit 854a9895 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
  sparc: Fix debugger syscall restart interactions.
  sparc: Fix ptrace() detach.
  sparc32: Don't twiddle PT_DTRACE in exec.
  sparc video: remove open boot prom code
parents 633331f3 28e61036
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1306,6 +1306,8 @@ ret_from_fork:
	.align	4
	.globl	linux_sparc_syscall
linux_sparc_syscall:
	sethi	%hi(PSR_SYSCALL), %l4
	or	%l0, %l4, %l0
	/* Direct access to user regs, must faster. */
	cmp	%g1, NR_SYSCALLS
	bgeu	linux_sparc_ni_syscall
+0 −5
Original line number Diff line number Diff line
@@ -638,11 +638,6 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
			  (char __user * __user *)regs->u_regs[base + UREG_I2],
			  regs);
	putname(filename);
	if (error == 0) {
		task_lock(current);
		current->ptrace &= ~PT_DTRACE;
		task_unlock(current);
	}
out:
	return error;
}
+4 −2
Original line number Diff line number Diff line
@@ -170,8 +170,8 @@ static int genregs32_set(struct task_struct *target,
		switch (pos) {
		case 32: /* PSR */
			psr = regs->psr;
			psr &= ~PSR_ICC;
			psr |= (reg & PSR_ICC);
			psr &= ~(PSR_ICC | PSR_SYSCALL);
			psr |= (reg & (PSR_ICC | PSR_SYSCALL));
			regs->psr = psr;
			break;
		case 33: /* PC */
@@ -441,6 +441,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
		break;

	default:
		if (request == PTRACE_SPARC_DETACH)
			request = PTRACE_DETACH;
		ret = ptrace_request(child, request, addr, data);
		break;
	}
+8 −3
Original line number Diff line number Diff line
@@ -50,8 +50,9 @@ rtrap_7win_patch5: and %g1, 0x7f, %g1
ret_trap_entry:
ret_trap_lockless_ipi:
	andcc	%t_psr, PSR_PS, %g0
	sethi	%hi(PSR_SYSCALL), %g1
	be	1f
	 nop
	 andn	%t_psr, %g1, %t_psr

	wr	%t_psr, 0x0, %psr
	b	ret_trap_kernel
@@ -73,7 +74,6 @@ signal_p:
	 ld	[%sp + STACKFRAME_SZ + PT_PSR], %t_psr

	mov	%l5, %o1
	mov	%l6, %o2
	call	do_signal
	 add	%sp, STACKFRAME_SZ, %o0	! pt_regs ptr

@@ -81,6 +81,8 @@ signal_p:
	ld	[%sp + STACKFRAME_SZ + PT_PSR], %t_psr
	clr	%l6
ret_trap_continue:
	sethi	%hi(PSR_SYSCALL), %g1
	andn	%t_psr, %g1, %t_psr
	wr	%t_psr, 0x0, %psr
	WRITE_PAUSE

@@ -137,8 +139,9 @@ ret_trap_userwins_ok:
	LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
	or	%t_pc, %t_npc, %g2
	andcc	%g2, 0x3, %g0
	sethi	%hi(PSR_SYCALL), %g2
	be	1f
	 nop
	 andn	%t_psr, %g2, %t_psr

	b	ret_trap_unaligned_pc
	 add	%sp, STACKFRAME_SZ, %o0
@@ -201,6 +204,8 @@ rtrap_patch5: and %g1, 0xff, %g1
1:
	LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
2:
	sethi	%hi(PSR_SYSCALL), %twin_tmp1
	andn	%t_psr, %twin_tmp1, %t_psr
	wr	%t_psr, 0x0, %psr
	WRITE_PAUSE

+28 −36
Original line number Diff line number Diff line
@@ -145,6 +145,9 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
	regs->psr = (up_psr & ~(PSR_ICC | PSR_EF))
		  | (regs->psr & (PSR_ICC | PSR_EF));

	/* Prevent syscall restart.  */
	pt_regs_clear_syscall(regs);

	err |= __get_user(fpu_save, &sf->fpu_save);

	if (fpu_save)
@@ -199,6 +202,9 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)

	regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC);

	/* Prevent syscall restart.  */
	pt_regs_clear_syscall(regs);

	err |= __get_user(fpu_save, &sf->fpu_save);

	if (fpu_save)
@@ -507,26 +513,36 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 */
asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall)
asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0)
{
	siginfo_t info;
	struct sparc_deliver_cookie cookie;
	struct k_sigaction ka;
	int signr;
	int restart_syscall;
	sigset_t *oldset;
	siginfo_t info;
	int signr;

	cookie.restart_syscall = restart_syscall;
	cookie.orig_i0 = orig_i0;
	if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
		restart_syscall = 1;
	else
		restart_syscall = 0;

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

	signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
	signr = get_signal_to_deliver(&info, &ka, regs, NULL);

	/* If the debugger messes with the program counter, it clears
	 * the software "in syscall" bit, directing us to not perform
	 * a syscall restart.
	 */
	if (restart_syscall && !pt_regs_is_syscall(regs))
		restart_syscall = 0;

	if (signr > 0) {
		if (cookie.restart_syscall)
			syscall_restart(cookie.orig_i0, regs, &ka.sa);
		if (restart_syscall)
			syscall_restart(orig_i0, regs, &ka.sa);
		handle_signal(signr, &ka, &info, oldset, regs);

		/* a signal was successfully delivered; the saved
@@ -538,16 +554,16 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
			clear_thread_flag(TIF_RESTORE_SIGMASK);
		return;
	}
	if (cookie.restart_syscall &&
	if (restart_syscall &&
	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
		/* replay the system call when we are done */
		regs->u_regs[UREG_I0] = cookie.orig_i0;
		regs->u_regs[UREG_I0] = orig_i0;
		regs->pc -= 4;
		regs->npc -= 4;
	}
	if (cookie.restart_syscall &&
	if (restart_syscall &&
	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
		regs->u_regs[UREG_G1] = __NR_restart_syscall;
		regs->pc -= 4;
@@ -599,27 +615,3 @@ do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr,
out:
	return ret;
}

void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
{
	struct sparc_deliver_cookie *cp = cookie;

	if (cp->restart_syscall &&
	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
		/* replay the system call when we are done */
		regs->u_regs[UREG_I0] = cp->orig_i0;
		regs->pc -= 4;
		regs->npc -= 4;
		cp->restart_syscall = 0;
	}

	if (cp->restart_syscall &&
	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
		regs->u_regs[UREG_G1] = __NR_restart_syscall;
		regs->pc -= 4;
		regs->npc -= 4;
		cp->restart_syscall = 0;
	}
}
Loading