Commit 6ca0c1d6 authored by David S. Miller's avatar David S. Miller

[SPARC64]: Check _TIF_SYSCALL_SUCCESS before syscall return value.

We might have to clear the flag, and if we do not
then subsequent syscalls can get confused.

Bug easily triggered by suspending emacs in a pty
and then resuming, select() returns due to a pending
signal but because _TIF_SYSCALL_SUCCESS is erroneously
set by a previous syscall -514 ends up slipping into
userspace.  Oops.
parent 26623ba3
...@@ -1751,12 +1751,25 @@ ret_sys_call: ...@@ -1751,12 +1751,25 @@ ret_sys_call:
ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
sra %o0, 0, %o0 sra %o0, 0, %o0
mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
cmp %o0, -ENOIOCTLCMD
sllx %g2, 32, %g2 sllx %g2, 32, %g2
/* Check if force_successful_syscall_return()
* was invoked.
*/
ldx [%curptr + TI_FLAGS], %l0
andcc %l0, _TIF_SYSCALL_SUCCESS, %g0
be,pt %icc, 1f
andn %l0, _TIF_SYSCALL_SUCCESS, %l0
ba,pt %xcc, 80f
stx %l0, [%curptr + TI_FLAGS]
1:
cmp %o0, -ENOIOCTLCMD
bgeu,pn %xcc, 1f bgeu,pn %xcc, 1f
andcc %l0, _TIF_SYSCALL_TRACE, %l6 andcc %l0, _TIF_SYSCALL_TRACE, %l6
80: 80:
andn %g3, %g2, %g3 /* System call success, clear Carry condition code. */ /* System call success, clear Carry condition code. */
andn %g3, %g2, %g3
stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
bne,pn %icc, linux_syscall_trace2 bne,pn %icc, linux_syscall_trace2
add %l1, 0x4, %l2 ! npc = npc+4 add %l1, 0x4, %l2 ! npc = npc+4
...@@ -1765,28 +1778,17 @@ ret_sys_call: ...@@ -1765,28 +1778,17 @@ ret_sys_call:
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
1: 1:
/* Really a failure? Check if force_successful_syscall_return()
* was invoked.
*/
ldx [%curptr + TI_FLAGS], %l0 ! Load
andcc %l0, _TIF_SYSCALL_SUCCESS, %g0
be,pt %icc, 1f
andcc %l0, _TIF_SYSCALL_TRACE, %l6
andn %l0, _TIF_SYSCALL_SUCCESS, %l0
ba,pt %xcc, 80b
stx %l0, [%curptr + TI_FLAGS]
/* System call failure, set Carry condition code. /* System call failure, set Carry condition code.
* Also, get abs(errno) to return to the process. * Also, get abs(errno) to return to the process.
*/ */
1: andcc %l0, _TIF_SYSCALL_TRACE, %l6
sub %g0, %o0, %o0 sub %g0, %o0, %o0
or %g3, %g2, %g3 or %g3, %g2, %g3
stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
mov 1, %l6 mov 1, %l6
stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
bne,pn %icc, linux_syscall_trace2 bne,pn %icc, linux_syscall_trace2
add %l1, 0x4, %l2 !npc = npc+4 add %l1, 0x4, %l2 ! npc = npc+4
stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
b,pt %xcc, rtrap b,pt %xcc, rtrap
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment