[SPARC64]: Move syscall success and newchild state out of thread flags.

These two bits were accesses non-atomically from assembler
code.  So, in order to eliminate any potential races resulting
from that, move these pieces of state into two bytes elsewhere
in struct thread_info.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2005-07-24 19:36:26 -07:00
parent cdd5186f75
commit db7d9a4eb7
7 changed files with 27 additions and 24 deletions

View File

@@ -1600,11 +1600,11 @@ sys_clone: flushw
ba,pt %xcc, sparc_do_fork
add %sp, PTREGS_OFF, %o2
ret_from_syscall:
/* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in
* %o7 for us. Check performance counter stuff too.
/* Clear current_thread_info()->new_child, and
* check performance counter stuff too.
*/
andn %o7, _TIF_NEWCHILD, %l0
stx %l0, [%g6 + TI_FLAGS]
stb %g0, [%g6 + TI_NEW_CHILD]
ldx [%g6 + TI_FLAGS], %l0
call schedule_tail
mov %g7, %o0
andcc %l0, _TIF_PERFCTR, %g0
@@ -1720,12 +1720,11 @@ ret_sys_call:
/* 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
ldub [%curptr + TI_SYS_NOERROR], %l0
brz,pt %l0, 1f
nop
ba,pt %xcc, 80f
stx %l0, [%curptr + TI_FLAGS]
stb %g0, [%curptr + TI_SYS_NOERROR]
1:
cmp %o0, -ERESTART_RESTARTBLOCK

View File

@@ -621,8 +621,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ));
t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) |
_TIF_NEWCHILD |
(((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT);
t->new_child = 1;
t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS;
t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct sparc_stackf));
t->fpsaved[0] = 0;

View File

@@ -137,7 +137,7 @@ void __init smp_callin(void)
/* Clear this or we will die instantly when we
* schedule back to this idler...
*/
clear_thread_flag(TIF_NEWCHILD);
current_thread_info()->new_child = 0;
/* Attach to the address space of init_task. */
atomic_inc(&init_mm.mm_count);

View File

@@ -2125,6 +2125,8 @@ void __init trap_init(void)
TI_PCR != offsetof(struct thread_info, pcr_reg) ||
TI_CEE_STUFF != offsetof(struct thread_info, cee_stuff) ||
TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) ||
TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) ||
TI_FPREGS != offsetof(struct thread_info, fpregs) ||
(TI_FPREGS & (64 - 1)))
thread_info_offsets_are_bolixed_dave();