diff options
author | Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | 2007-03-10 03:23:03 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-03-16 16:37:28 +1100 |
commit | f144e7c7272bf527c380bffaa5e789dc28a09d8d (patch) | |
tree | 18139c591b245d3f60bd074ca7321ed111722596 /arch/powerpc/kernel/process.c | |
parent | db98e0b434a6265c451ffe94ec0a29b8d0aaf587 (diff) | |
download | blackbird-op-linux-f144e7c7272bf527c380bffaa5e789dc28a09d8d.tar.gz blackbird-op-linux-f144e7c7272bf527c380bffaa5e789dc28a09d8d.zip |
[POWERPC] Fix atomicity of TIF update in flush_thread()
Fix atomicity of TIF update in flush_thread() for powerpc
Fixes it correctly with *_ti_thread_flag.
Race :
parent process executing :
sys_ptrace()
(lock_kernel())
(ptrace_get_task_struct(pid))
arch_ptrace()
ptrace_detach()
ptrace_disable(child);
clear_singlestep(child);
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
(which clears the TIF_SINGLESTEP flag atomically from a different
process)
(put_task_struct(child))
(unlock_kernel())
And at the same time, in the child process :
sys_execve()
do_execve()
search_binary_handler()
load_elf_binary()
flush_old_exec()
flush_thread()
doing a non-atomic thread flag update
Applies on 2.6.20.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r-- | arch/powerpc/kernel/process.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index f3d4dd580dd6..e53b2988d1bf 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -465,8 +465,13 @@ void flush_thread(void) #ifdef CONFIG_PPC64 struct thread_info *t = current_thread_info(); - if (t->flags & _TIF_ABI_PENDING) - t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT); + if (test_ti_thread_flag(t, TIF_ABI_PENDING)) { + clear_ti_thread_flag(t, TIF_ABI_PENDING); + if (test_ti_thread_flag(t, TIF_32BIT)) + clear_ti_thread_flag(t, TIF_32BIT); + else + set_ti_thread_flag(t, TIF_32BIT); + } #endif discard_lazy_cpu_state(); |