Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ struct task_struct;
 * 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.
 */
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 struct task_struct *ll_task;
@@ -66,11 +66,13 @@ do { \

#define switch_to(prev, next, last)					\
do {									\
	u32 __usedfpu;							\
	__mips_mt_fpaff_switch_to(prev);				\
	if (cpu_has_dsp)						\
		__save_dsp(prev);					\
	__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)

#define finish_arch_switch(prev)					\
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@

/*
 * task_struct *resume(task_struct *prev, task_struct *next,
 *                     struct thread_info *next_ti)
 *                     struct thread_info *next_ti, int usedfpu)
 */
	.align	7
	LEAF(resume)
+3 −12
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@

/*
 * task_struct *resume(task_struct *prev, task_struct *next,
 *                     struct thread_info *next_ti) )
 *                     struct thread_info *next_ti, int usedfpu)
 */
LEAF(resume)
	mfc0	t1, CP0_STATUS
@@ -51,18 +51,9 @@ LEAF(resume)
	cpu_save_nonscratch a0
	sw	ra, THREAD_REG31(a0)

	/*
	 * 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
	beqz	a3, 1f

	and	t0, t0, t1
	sw	t0, TI_FLAGS(t3)
	PTR_L	t3, TASK_THREAD_INFO(a0)

	/*
	 * clear saved user stack CU1 bit
+3 −9
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@

/*
 * task_struct *resume(task_struct *prev, task_struct *next,
 *                     struct thread_info *next_ti)
 *                     struct thread_info *next_ti, int usedfpu)
 */
	.align	5
	LEAF(resume)
@@ -53,16 +53,10 @@
	/*
	 * 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
	LONG_S	t0, TI_FLAGS(t3)
	beqz    a3, 1f

	PTR_L	t3, TASK_THREAD_INFO(a0)
	/*
	 * clear saved user stack CU1 bit
	 */