powerpc: Disable interrupts in 64-bit kernel FP and vector faults
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 1 Mar 2012 04:47:44 +0000 (15:47 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 8 Mar 2012 23:55:10 +0000 (10:55 +1100)
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.

arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/traps.c

index 573613d747accafb3fb08c01a56ba0f6d3f226b8..3de9993c5c65dfcecc93a47aa8dba3a6cd4729e4 100644 (file)
@@ -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
 
index d8ff6d37fc4d995589edf7c0725070f4b8d2d521..0fb42ae21694b6e011ed8806283c4063ddc5169f 100644 (file)
@@ -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
 
index 5d40e592ffcb904ca01cc94e31a46964f38accaf..a750409ccc4e25b2743456bc3b492166b9f8c1c7 100644 (file)
@@ -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;