powerpc: Add transactional memory unavaliable execption handler
authorMichael Neuling <mikey@neuling.org>
Wed, 13 Feb 2013 16:21:38 +0000 (16:21 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 15 Feb 2013 06:02:22 +0000 (17:02 +1100)
These should never happen since we always turn on MSR TM when in userspace. We
don't do lazy TM.

Hence if we hit this, we barf and kill the task as something's gone horribly
wrong.

Signed-off-by: Matt Evans <matt@ozlabs.org>
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/traps.c

index b9bcf21dbb114ef5746f062a88b079273eb889c3..c6b88c1f3ebd6571b0d05109ae5d252b81929481 100644 (file)
@@ -336,6 +336,11 @@ vsx_unavailable_pSeries_1:
        EXCEPTION_PROLOG_0(PACA_EXGEN)
        b       vsx_unavailable_pSeries
 
+       . = 0xf60
+       SET_SCRATCH0(r13)
+       EXCEPTION_PROLOG_0(PACA_EXGEN)
+       b       tm_unavailable_pSeries
+
 #ifdef CONFIG_CBE_RAS
        STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
        KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
@@ -550,6 +555,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
        KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20)
        STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
        KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40)
+       STD_EXCEPTION_PSERIES_OOL(0xf60, tm_unavailable)
+       KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf60)
 
 /*
  * An interrupt came in while soft-disabled. We set paca->irq_happened, then:
@@ -852,6 +859,12 @@ vsx_unavailable_relon_pSeries_1:
        EXCEPTION_PROLOG_0(PACA_EXGEN)
        b       vsx_unavailable_relon_pSeries
 
+tm_unavailable_relon_pSeries_1:
+       . = 0x4f60
+       SET_SCRATCH0(r13)
+       EXCEPTION_PROLOG_0(PACA_EXGEN)
+       b       tm_unavailable_relon_pSeries
+
        STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint)
 #ifdef CONFIG_PPC_DENORMALISATION
        . = 0x5500
@@ -1201,6 +1214,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        bl      .vsx_unavailable_exception
        b       .ret_from_except
 
+       .align  7
+       .globl tm_unavailable_common
+tm_unavailable_common:
+       EXCEPTION_PROLOG_COMMON(0xf60, PACA_EXGEN)
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .tm_unavailable_exception
+       b       .ret_from_except
+
        .align  7
        .globl  __end_handlers
 __end_handlers:
@@ -1220,6 +1242,7 @@ __end_handlers:
        STD_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
        STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
        STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
+       STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, tm_unavailable)
 
 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
 /*
index bd5de5deaf5157b1991b5b970427c691539a1287..f829e05d8b1b68cda113718d7af62dfbaece9bf3 100644 (file)
@@ -1168,6 +1168,27 @@ void vsx_unavailable_exception(struct pt_regs *regs)
        die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT);
 }
 
+void tm_unavailable_exception(struct pt_regs *regs)
+{
+       /* We restore the interrupt state now */
+       if (!arch_irq_disabled_regs(regs))
+               local_irq_enable();
+
+       /* Currently we never expect a TMU exception.  Catch
+        * this and kill the process!
+        */
+       printk(KERN_EMERG "Unexpected TM unavailable exception at %lx "
+              "(msr %lx)\n",
+              regs->nip, regs->msr);
+
+       if (user_mode(regs)) {
+               _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+               return;
+       }
+
+       die("Unexpected TM unavailable exception", regs, SIGABRT);
+}
+
 void performance_monitor_exception(struct pt_regs *regs)
 {
        __get_cpu_var(irq_stat).pmu_irqs++;