diff options
-rw-r--r-- | arch/mips/include/asm/kdebug.h | 3 | ||||
-rw-r--r-- | arch/mips/kernel/genex.S | 14 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 16 |
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 | ||
1396 | asmlinkage void do_msa_fpe(struct pt_regs *regs) | 1401 | asmlinkage 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); |
1416 | out: | ||
1403 | exception_exit(prev_state); | 1417 | exception_exit(prev_state); |
1404 | } | 1418 | } |
1405 | 1419 | ||