[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:
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
|
Reference in New Issue
Block a user