Commit 7daef8f2 authored by Paul Burton's avatar Paul Burton Committed by Ralf Baechle

MIPS: consistently clear MSA flags when starting & copying threads

The TIF_MSA_CTX_LIVE flag (indicating that a task has MSA context which
needs to be preserved) was being cleared in start_thread, but the
TIF_USEDMSA flag (indicating that a task has used MSA in this timeslice)
was not. In copy_thread neither flag was cleared, but both need to be.
Without clearing these flags the kernel will proceed to attempt to save
MSA context when the task is context switched out, and if the task had
not used MSA in the meantime then it will fail because MSA or the FPU
are disabled. The end result is typically:

  do_cpu invoked from kernel context![#1]:
  CPU: 0 PID: 99 Comm: sh Not tainted 3.16.0-rc4-00025-g6dc9476-dirty #88
  task: 8f23dc60 ti: 8f1d8000 task.ti: 8f1d8000
  ...
  Call Trace:
  [<8010edbc>] resume+0x5c/0x280
  [<80481e0c>] __schedule+0x370/0x800
  [<80104838>] work_resched+0x8/0x2c

Fix by consistently clearing both flags in both functions.
Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/7309/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 37cddff8
...@@ -66,6 +66,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) ...@@ -66,6 +66,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
clear_used_math(); clear_used_math();
clear_fpu_owner(); clear_fpu_owner();
init_dsp(); init_dsp();
clear_thread_flag(TIF_USEDMSA);
clear_thread_flag(TIF_MSA_CTX_LIVE); clear_thread_flag(TIF_MSA_CTX_LIVE);
disable_msa(); disable_msa();
regs->cp0_epc = pc; regs->cp0_epc = pc;
...@@ -141,6 +142,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -141,6 +142,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
clear_tsk_thread_flag(p, TIF_USEDFPU); clear_tsk_thread_flag(p, TIF_USEDFPU);
clear_tsk_thread_flag(p, TIF_USEDMSA);
clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE);
#ifdef CONFIG_MIPS_MT_FPAFF #ifdef CONFIG_MIPS_MT_FPAFF
clear_tsk_thread_flag(p, TIF_FPUBOUND); clear_tsk_thread_flag(p, TIF_FPUBOUND);
......
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