Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=07500b0d855b7f3f47ca263b21b6397d743d45d2
Commit:     07500b0d855b7f3f47ca263b21b6397d743d45d2
Parent:     98ce472181e760a552314850c238b14bbf3f04ec
Author:     Ralf Baechle <[EMAIL PROTECTED]>
AuthorDate: Tue Oct 30 17:25:26 2007 +0000
Committer:  Ralf Baechle <[EMAIL PROTECTED]>
CommitDate: Mon Nov 26 17:26:13 2007 +0000

    [MIPS] Fix context DSP context / TLS pointer switching bug for new threads.
    
    A new born thread starts execution not in schedule but rather in
    ret_from_fork which results in it bypassing the part of the code to
    load a new context written in C which are the DSP context and the
    userlocal register which Linux uses for the TLS pointer.  Frequently
    we were just getting away with this bug for a number of reasons:
    
     o Real world application scenarios are very unlikely to use clone or fork
       in blocks of DSP code.
     o Linux by default runs the child process right after the fork, so the
       child by luck will find all the right context in the DSP and userlocal
       registers.
     o So far the rdhwr instruction was emulated on all hardware so userlocal
       wasn't getting referenced at all and the emulation wasn't suffering
       from the issue since it gets it's value straight from the thread's
       thread_info.
    
    Fixed by moving the code to load the context from switch_to() to
    finish_arch_switch which will be called by newborn and old threads.
    
    Signed-off-by: Ralf Baechle <[EMAIL PROTECTED]>
---
 include/asm-mips/system.h |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 90e4b40..1030562 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -68,11 +68,15 @@ do {                                                        
                \
        if (cpu_has_dsp)                                                \
                __save_dsp(prev);                                       \
        (last) = resume(prev, next, task_thread_info(next));            \
+} while (0)
+
+#define finish_arch_switch(prev)                                       \
+do {                                                                   \
        if (cpu_has_dsp)                                                \
                __restore_dsp(current);                                 \
        if (cpu_has_userlocal)                                          \
-               write_c0_userlocal(task_thread_info(current)->tp_value);\
-} while(0)
+               write_c0_userlocal(current_thread_info()->tp_value);    \
+} while (0)
 
 static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
 {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to