summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-03-01 15:47:44 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-03-09 10:55:10 +1100
commit9f2f79e3a3c19ae745d0439d6e0eed31df28de3c (patch)
tree0f68f198e3ce6233c5c96d0267de9a73832858a4
parenta546498f3bf9aac311c66f965186373aee2ca0b0 (diff)
downloadblackbird-op-linux-9f2f79e3a3c19ae745d0439d6e0eed31df28de3c.tar.gz
blackbird-op-linux-9f2f79e3a3c19ae745d0439d6e0eed31df28de3c.zip
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:
/* we can probably do a shorter exception entry for that one... */
EXCEPTION_COMMON(0x800, PACA_EXGEN, INTS_KEEP)
bne 1f /* if from user, just load it up */
+ INTS_DISABLE_ALL
bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
- INTS_RESTORE_HARD
bl .kernel_fp_unavailable_exception
BUG_OPCODE
1: ld r12,_MSR(r1)
@@ -391,10 +391,9 @@ interrupt_end_book3e:
/* Auxiliary Processor Unavailable Interrupt */
START_EXCEPTION(ap_unavailable);
NORMAL_EXCEPTION_PROLOG(0xf20, PROLOG_ADDITION_NONE)
- EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_KEEP)
- addi r3,r1,STACK_FRAME_OVERHEAD
+ EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_DISABLE_ALL)
bl .save_nvgprs
- INTS_RESTORE_HARD
+ addi r3,r1,STACK_FRAME_OVERHEAD
bl .unknown_exception
b .ret_from_except
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:
EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
bne 1f /* if from user, just load it up */
bl .save_nvgprs
+ DISABLE_INTS
addi r3,r1,STACK_FRAME_OVERHEAD
- ENABLE_INTS
bl .kernel_fp_unavailable_exception
BUG_OPCODE
1: bl .load_up_fpu
@@ -782,8 +782,8 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif
bl .save_nvgprs
+ DISABLE_INTS
addi r3,r1,STACK_FRAME_OVERHEAD
- ENABLE_INTS
bl .altivec_unavailable_exception
b .ret_from_except
@@ -798,8 +798,8 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_VSX)
#endif
bl .save_nvgprs
+ DISABLE_INTS
addi r3,r1,STACK_FRAME_OVERHEAD
- ENABLE_INTS
bl .vsx_unavailable_exception
b .ret_from_except
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)
addr, regs->nip, regs->link, code);
}
+ if (!arch_irq_disabled_regs(regs))
+ local_irq_enable();
+
memset(&info, 0, sizeof(info));
info.si_signo = signr;
info.si_code = code;
OpenPOWER on IntegriCloud