aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonid Yegoshin <yegoshin@mips.com>2012-07-19 03:11:14 -0400
committerRalf Baechle <ralf@linux-mips.org>2012-07-19 05:23:43 -0400
commit2dd17030c940ef1199a07b095ec79c4660fa8734 (patch)
tree34261c3c27f418a785ef127afe6a1f0109310a53
parentdc34b05fea0cc9a869863b929f37f1e8ce30edf4 (diff)
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: Leonid Yegoshin <yegoshin@mips.com> Signed-off-by: Steven J. Hill <sjhill@mips.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3784/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/include/asm/switch_to.h6
-rw-r--r--arch/mips/kernel/octeon_switch.S2
-rw-r--r--arch/mips/kernel/r2300_switch.S15
-rw-r--r--arch/mips/kernel/r4k_switch.S12
4 files changed, 11 insertions, 24 deletions
diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h
index 5d33621b565..4f8ddba8c36 100644
--- a/arch/mips/include/asm/switch_to.h
+++ b/arch/mips/include/asm/switch_to.h
@@ -22,7 +22,7 @@ struct task_struct;
22 * switch_to(n) should switch tasks to task nr n, first 22 * switch_to(n) should switch tasks to task nr n, first
23 * checking that n isn't the current task, in which case it does nothing. 23 * checking that n isn't the current task, in which case it does nothing.
24 */ 24 */
25extern asmlinkage void *resume(void *last, void *next, void *next_ti); 25extern asmlinkage void *resume(void *last, void *next, void *next_ti, u32 __usedfpu);
26 26
27extern unsigned int ll_bit; 27extern unsigned int ll_bit;
28extern struct task_struct *ll_task; 28extern struct task_struct *ll_task;
@@ -66,11 +66,13 @@ do { \
66 66
67#define switch_to(prev, next, last) \ 67#define switch_to(prev, next, last) \
68do { \ 68do { \
69 u32 __usedfpu; \
69 __mips_mt_fpaff_switch_to(prev); \ 70 __mips_mt_fpaff_switch_to(prev); \
70 if (cpu_has_dsp) \ 71 if (cpu_has_dsp) \
71 __save_dsp(prev); \ 72 __save_dsp(prev); \
72 __clear_software_ll_bit(); \ 73 __clear_software_ll_bit(); \
73 (last) = resume(prev, next, task_thread_info(next)); \ 74 __usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU); \
75 (last) = resume(prev, next, task_thread_info(next), __usedfpu); \
74} while (0) 76} while (0)
75 77
76#define finish_arch_switch(prev) \ 78#define finish_arch_switch(prev) \
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index ce89c806170..0441f54b2a6 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -31,7 +31,7 @@
31 31
32/* 32/*
33 * task_struct *resume(task_struct *prev, task_struct *next, 33 * task_struct *resume(task_struct *prev, task_struct *next,
34 * struct thread_info *next_ti) 34 * struct thread_info *next_ti, int usedfpu)
35 */ 35 */
36 .align 7 36 .align 7
37 LEAF(resume) 37 LEAF(resume)
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index 293898391e6..9c51be5a163 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -43,7 +43,7 @@
43 43
44/* 44/*
45 * task_struct *resume(task_struct *prev, task_struct *next, 45 * task_struct *resume(task_struct *prev, task_struct *next,
46 * struct thread_info *next_ti) ) 46 * struct thread_info *next_ti, int usedfpu)
47 */ 47 */
48LEAF(resume) 48LEAF(resume)
49 mfc0 t1, CP0_STATUS 49 mfc0 t1, CP0_STATUS
@@ -51,18 +51,9 @@ LEAF(resume)
51 cpu_save_nonscratch a0 51 cpu_save_nonscratch a0
52 sw ra, THREAD_REG31(a0) 52 sw ra, THREAD_REG31(a0)
53 53
54 /* 54 beqz a3, 1f
55 * check if we need to save FPU registers
56 */
57 lw t3, TASK_THREAD_INFO(a0)
58 lw t0, TI_FLAGS(t3)
59 li t1, _TIF_USEDFPU
60 and t2, t0, t1
61 beqz t2, 1f
62 nor t1, zero, t1
63 55
64 and t0, t0, t1 56 PTR_L t3, TASK_THREAD_INFO(a0)
65 sw t0, TI_FLAGS(t3)
66 57
67 /* 58 /*
68 * clear saved user stack CU1 bit 59 * clear saved user stack CU1 bit
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 9414f935446..42d2a393842 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -41,7 +41,7 @@
41 41
42/* 42/*
43 * task_struct *resume(task_struct *prev, task_struct *next, 43 * task_struct *resume(task_struct *prev, task_struct *next,
44 * struct thread_info *next_ti) 44 * struct thread_info *next_ti, int usedfpu)
45 */ 45 */
46 .align 5 46 .align 5
47 LEAF(resume) 47 LEAF(resume)
@@ -53,16 +53,10 @@
53 /* 53 /*
54 * check if we need to save FPU registers 54 * check if we need to save FPU registers
55 */ 55 */
56 PTR_L t3, TASK_THREAD_INFO(a0)
57 LONG_L t0, TI_FLAGS(t3)
58 li t1, _TIF_USEDFPU
59 and t2, t0, t1
60 beqz t2, 1f
61 nor t1, zero, t1
62 56
63 and t0, t0, t1 57 beqz a3, 1f
64 LONG_S t0, TI_FLAGS(t3)
65 58
59 PTR_L t3, TASK_THREAD_INFO(a0)
66 /* 60 /*
67 * clear saved user stack CU1 bit 61 * clear saved user stack CU1 bit
68 */ 62 */