Commit 2dd17030 authored by Leonid Yegoshin's avatar Leonid Yegoshin Committed by Ralf Baechle

MIPS: Fix race condition with FPU thread task flag during context switch.

[ralf@linux-mips.org: Cosmetic changes; also fixed up r2300_switch.S and
octeon_switch.S which needed similar modifications.]
Signed-off-by: default avatarLeonid Yegoshin <yegoshin@mips.com>
Signed-off-by: default avatarSteven J. Hill <sjhill@mips.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/3784/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent dc34b05f
...@@ -22,7 +22,7 @@ struct task_struct; ...@@ -22,7 +22,7 @@ struct task_struct;
* switch_to(n) should switch tasks to task nr n, first * switch_to(n) should switch tasks to task nr n, first
* checking that n isn't the current task, in which case it does nothing. * checking that n isn't the current task, in which case it does nothing.
*/ */
extern asmlinkage void *resume(void *last, void *next, void *next_ti); extern asmlinkage void *resume(void *last, void *next, void *next_ti, u32 __usedfpu);
extern unsigned int ll_bit; extern unsigned int ll_bit;
extern struct task_struct *ll_task; extern struct task_struct *ll_task;
...@@ -66,11 +66,13 @@ do { \ ...@@ -66,11 +66,13 @@ do { \
#define switch_to(prev, next, last) \ #define switch_to(prev, next, last) \
do { \ do { \
u32 __usedfpu; \
__mips_mt_fpaff_switch_to(prev); \ __mips_mt_fpaff_switch_to(prev); \
if (cpu_has_dsp) \ if (cpu_has_dsp) \
__save_dsp(prev); \ __save_dsp(prev); \
__clear_software_ll_bit(); \ __clear_software_ll_bit(); \
(last) = resume(prev, next, task_thread_info(next)); \ __usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU); \
(last) = resume(prev, next, task_thread_info(next), __usedfpu); \
} while (0) } while (0)
#define finish_arch_switch(prev) \ #define finish_arch_switch(prev) \
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
/* /*
* task_struct *resume(task_struct *prev, task_struct *next, * task_struct *resume(task_struct *prev, task_struct *next,
* struct thread_info *next_ti) * struct thread_info *next_ti, int usedfpu)
*/ */
.align 7 .align 7
LEAF(resume) LEAF(resume)
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
/* /*
* task_struct *resume(task_struct *prev, task_struct *next, * task_struct *resume(task_struct *prev, task_struct *next,
* struct thread_info *next_ti) ) * struct thread_info *next_ti, int usedfpu)
*/ */
LEAF(resume) LEAF(resume)
mfc0 t1, CP0_STATUS mfc0 t1, CP0_STATUS
...@@ -51,18 +51,9 @@ LEAF(resume) ...@@ -51,18 +51,9 @@ LEAF(resume)
cpu_save_nonscratch a0 cpu_save_nonscratch a0
sw ra, THREAD_REG31(a0) sw ra, THREAD_REG31(a0)
/* beqz a3, 1f
* check if we need to save FPU registers
*/
lw t3, TASK_THREAD_INFO(a0)
lw t0, TI_FLAGS(t3)
li t1, _TIF_USEDFPU
and t2, t0, t1
beqz t2, 1f
nor t1, zero, t1
and t0, t0, t1 PTR_L t3, TASK_THREAD_INFO(a0)
sw t0, TI_FLAGS(t3)
/* /*
* clear saved user stack CU1 bit * clear saved user stack CU1 bit
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
/* /*
* task_struct *resume(task_struct *prev, task_struct *next, * task_struct *resume(task_struct *prev, task_struct *next,
* struct thread_info *next_ti) * struct thread_info *next_ti, int usedfpu)
*/ */
.align 5 .align 5
LEAF(resume) LEAF(resume)
...@@ -53,16 +53,10 @@ ...@@ -53,16 +53,10 @@
/* /*
* check if we need to save FPU registers * check if we need to save FPU registers
*/ */
PTR_L t3, TASK_THREAD_INFO(a0)
LONG_L t0, TI_FLAGS(t3)
li t1, _TIF_USEDFPU
and t2, t0, t1
beqz t2, 1f
nor t1, zero, t1
and t0, t0, t1 beqz a3, 1f
LONG_S t0, TI_FLAGS(t3)
PTR_L t3, TASK_THREAD_INFO(a0)
/* /*
* clear saved user stack CU1 bit * clear saved user stack CU1 bit
*/ */
......
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