Preemption must be disabled throughout the process of enabling the FPU, enabling MSA & initialising the vector registers. Without doing so it is possible to lose the FPU or MSA whilst initialising them causing that initialisation to fail. Signed-off-by: Paul Burton <paul.burton@xxxxxxxxxx> --- arch/mips/include/asm/fpu.h | 4 ---- arch/mips/kernel/traps.c | 12 ++++++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index 71d97eb..4d0aeda 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -164,8 +164,6 @@ static inline int init_fpu(void) { int ret = 0; - preempt_disable(); - if (cpu_has_fpu) { ret = __own_fpu(); if (!ret) @@ -173,8 +171,6 @@ static inline int init_fpu(void) } else fpu_emulator_init_fpu(); - preempt_enable(); - return ret; } diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 58a067f..0528246 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1092,6 +1092,7 @@ static int enable_restore_fp_context(int msa) if (!used_math()) { /* First time FP context user. */ + preempt_disable(); err = init_fpu(); if (msa && !err) { enable_msa(); @@ -1099,6 +1100,7 @@ static int enable_restore_fp_context(int msa) set_thread_flag(TIF_USEDMSA); set_thread_flag(TIF_MSA_CTX_LIVE); } + preempt_enable(); if (!err) set_used_math(); return err; @@ -1138,10 +1140,11 @@ static int enable_restore_fp_context(int msa) * This task is using or has previously used MSA. Thus we require * that Status.FR == 1. */ + preempt_disable(); was_fpu_owner = is_fpu_owner(); - err = own_fpu(0); + err = own_fpu_inatomic(0); if (err) - return err; + goto out; enable_msa(); write_msa_csr(current->thread.fpu.msacsr); @@ -1156,7 +1159,7 @@ static int enable_restore_fp_context(int msa) */ if (!test_and_set_thread_flag(TIF_MSA_CTX_LIVE) && was_fpu_owner) { _clear_msa_upper(); - return 0; + goto out; } /* We need to restore the vector context. */ @@ -1165,7 +1168,8 @@ static int enable_restore_fp_context(int msa) /* Restore the scalar FP control & status register */ if (!was_fpu_owner) asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31)); - +out: + preempt_enable(); return 0; } -- 2.0.1