aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/include/asm/kdebug.h3
-rw-r--r--arch/mips/kernel/genex.S14
-rw-r--r--arch/mips/kernel/traps.c16
3 files changed, 21 insertions, 12 deletions
diff --git a/arch/mips/include/asm/kdebug.h b/arch/mips/include/asm/kdebug.h
index 6a9af5fcb5d7..cba22ab7ad4d 100644
--- a/arch/mips/include/asm/kdebug.h
+++ b/arch/mips/include/asm/kdebug.h
@@ -10,7 +10,8 @@ enum die_val {
10 DIE_RI, 10 DIE_RI,
11 DIE_PAGE_FAULT, 11 DIE_PAGE_FAULT,
12 DIE_BREAK, 12 DIE_BREAK,
13 DIE_SSTEPBP 13 DIE_SSTEPBP,
14 DIE_MSAFP
14}; 15};
15 16
16#endif /* _ASM_MIPS_KDEBUG_H */ 17#endif /* _ASM_MIPS_KDEBUG_H */
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 86e22422d08c..af42e7003f12 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -360,21 +360,15 @@ NESTED(nmi_handler, PT_SIZE, sp)
360 .set mips1 360 .set mips1
361 SET_HARDFLOAT 361 SET_HARDFLOAT
362 cfc1 a1, fcr31 362 cfc1 a1, fcr31
363 li a2, ~(0x3f << 12)
364 and a2, a1
365 ctc1 a2, fcr31
366 .set pop 363 .set pop
367 TRACE_IRQS_ON 364 CLI
368 STI 365 TRACE_IRQS_OFF
369 .endm 366 .endm
370 367
371 .macro __build_clear_msa_fpe 368 .macro __build_clear_msa_fpe
372 _cfcmsa a1, MSA_CSR 369 _cfcmsa a1, MSA_CSR
373 li a2, ~(0x3f << 12) 370 CLI
374 and a1, a1, a2 371 TRACE_IRQS_OFF
375 _ctcmsa MSA_CSR, a1
376 TRACE_IRQS_ON
377 STI
378 .endm 372 .endm
379 373
380 .macro __build_clear_ade 374 .macro __build_clear_ade
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 8943ebe4d154..5b4d711f878d 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -788,6 +788,11 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
788 if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), 788 if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs),
789 SIGFPE) == NOTIFY_STOP) 789 SIGFPE) == NOTIFY_STOP)
790 goto out; 790 goto out;
791
792 /* Clear FCSR.Cause before enabling interrupts */
793 write_32bit_cp1_register(CP1_STATUS, fcr31 & ~FPU_CSR_ALL_X);
794 local_irq_enable();
795
791 die_if_kernel("FP exception in kernel code", regs); 796 die_if_kernel("FP exception in kernel code", regs);
792 797
793 if (fcr31 & FPU_CSR_UNI_X) { 798 if (fcr31 & FPU_CSR_UNI_X) {
@@ -1393,13 +1398,22 @@ out:
1393 exception_exit(prev_state); 1398 exception_exit(prev_state);
1394} 1399}
1395 1400
1396asmlinkage void do_msa_fpe(struct pt_regs *regs) 1401asmlinkage void do_msa_fpe(struct pt_regs *regs, unsigned int msacsr)
1397{ 1402{
1398 enum ctx_state prev_state; 1403 enum ctx_state prev_state;
1399 1404
1400 prev_state = exception_enter(); 1405 prev_state = exception_enter();
1406 if (notify_die(DIE_MSAFP, "MSA FP exception", regs, 0,
1407 regs_to_trapnr(regs), SIGFPE) == NOTIFY_STOP)
1408 goto out;
1409
1410 /* Clear MSACSR.Cause before enabling interrupts */
1411 write_msa_csr(msacsr & ~MSA_CSR_CAUSEF);
1412 local_irq_enable();
1413
1401 die_if_kernel("do_msa_fpe invoked from kernel context!", regs); 1414 die_if_kernel("do_msa_fpe invoked from kernel context!", regs);
1402 force_sig(SIGFPE, current); 1415 force_sig(SIGFPE, current);
1416out:
1403 exception_exit(prev_state); 1417 exception_exit(prev_state);
1404} 1418}
1405 1419