aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-02-29 23:47:44 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-03-08 18:55:10 -0500
commit9f2f79e3a3c19ae745d0439d6e0eed31df28de3c (patch)
tree0f68f198e3ce6233c5c96d0267de9a73832858a4
parenta546498f3bf9aac311c66f965186373aee2ca0b0 (diff)
powerpc: Disable interrupts in 64-bit kernel FP and vector faults
If we get a floating point, altivec or vsx unavaible interrupt in kernel, we trigger a kernel error. There is no point preserving the interrupt state, in fact, that can even make debugging harder as the processor state might change (we may even preempt) between taking the exception and landing in a debugger. So just make those 3 disable interrupts unconditionally. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> --- v2: On BookE only disable when hitting the kernel unavailable path, otherwise it will fail to restore softe as fast_exception_return doesn't do it.
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S7
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S6
-rw-r--r--arch/powerpc/kernel/traps.c3
3 files changed, 9 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 573613d747ac..3de9993c5c65 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -354,9 +354,9 @@ interrupt_end_book3e:
354 /* we can probably do a shorter exception entry for that one... */ 354 /* we can probably do a shorter exception entry for that one... */
355 EXCEPTION_COMMON(0x800, PACA_EXGEN, INTS_KEEP) 355 EXCEPTION_COMMON(0x800, PACA_EXGEN, INTS_KEEP)
356 bne 1f /* if from user, just load it up */ 356 bne 1f /* if from user, just load it up */
357 INTS_DISABLE_ALL
357 bl .save_nvgprs 358 bl .save_nvgprs
358 addi r3,r1,STACK_FRAME_OVERHEAD 359 addi r3,r1,STACK_FRAME_OVERHEAD
359 INTS_RESTORE_HARD
360 bl .kernel_fp_unavailable_exception 360 bl .kernel_fp_unavailable_exception
361 BUG_OPCODE 361 BUG_OPCODE
3621: ld r12,_MSR(r1) 3621: ld r12,_MSR(r1)
@@ -391,10 +391,9 @@ interrupt_end_book3e:
391/* Auxiliary Processor Unavailable Interrupt */ 391/* Auxiliary Processor Unavailable Interrupt */
392 START_EXCEPTION(ap_unavailable); 392 START_EXCEPTION(ap_unavailable);
393 NORMAL_EXCEPTION_PROLOG(0xf20, PROLOG_ADDITION_NONE) 393 NORMAL_EXCEPTION_PROLOG(0xf20, PROLOG_ADDITION_NONE)
394 EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_KEEP) 394 EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_DISABLE_ALL)
395 addi r3,r1,STACK_FRAME_OVERHEAD
396 bl .save_nvgprs 395 bl .save_nvgprs
397 INTS_RESTORE_HARD 396 addi r3,r1,STACK_FRAME_OVERHEAD
398 bl .unknown_exception 397 bl .unknown_exception
399 b .ret_from_except 398 b .ret_from_except
400 399
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index d8ff6d37fc4d..0fb42ae21694 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -762,8 +762,8 @@ fp_unavailable_common:
762 EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) 762 EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
763 bne 1f /* if from user, just load it up */ 763 bne 1f /* if from user, just load it up */
764 bl .save_nvgprs 764 bl .save_nvgprs
765 DISABLE_INTS
765 addi r3,r1,STACK_FRAME_OVERHEAD 766 addi r3,r1,STACK_FRAME_OVERHEAD
766 ENABLE_INTS
767 bl .kernel_fp_unavailable_exception 767 bl .kernel_fp_unavailable_exception
768 BUG_OPCODE 768 BUG_OPCODE
7691: bl .load_up_fpu 7691: bl .load_up_fpu
@@ -782,8 +782,8 @@ BEGIN_FTR_SECTION
782END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 782END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
783#endif 783#endif
784 bl .save_nvgprs 784 bl .save_nvgprs
785 DISABLE_INTS
785 addi r3,r1,STACK_FRAME_OVERHEAD 786 addi r3,r1,STACK_FRAME_OVERHEAD
786 ENABLE_INTS
787 bl .altivec_unavailable_exception 787 bl .altivec_unavailable_exception
788 b .ret_from_except 788 b .ret_from_except
789 789
@@ -798,8 +798,8 @@ BEGIN_FTR_SECTION
798END_FTR_SECTION_IFSET(CPU_FTR_VSX) 798END_FTR_SECTION_IFSET(CPU_FTR_VSX)
799#endif 799#endif
800 bl .save_nvgprs 800 bl .save_nvgprs
801 DISABLE_INTS
801 addi r3,r1,STACK_FRAME_OVERHEAD 802 addi r3,r1,STACK_FRAME_OVERHEAD
802 ENABLE_INTS
803 bl .vsx_unavailable_exception 803 bl .vsx_unavailable_exception
804 b .ret_from_except 804 b .ret_from_except
805 805
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 5d40e592ffcb..a750409ccc4e 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -247,6 +247,9 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
247 addr, regs->nip, regs->link, code); 247 addr, regs->nip, regs->link, code);
248 } 248 }
249 249
250 if (!arch_irq_disabled_regs(regs))
251 local_irq_enable();
252
250 memset(&info, 0, sizeof(info)); 253 memset(&info, 0, sizeof(info));
251 info.si_signo = signr; 254 info.si_signo = signr;
252 info.si_code = code; 255 info.si_code = code;