Commit d0c0c9a1 authored by Michael Neuling's avatar Michael Neuling Committed by Benjamin Herrenschmidt

powerpc: Add transactional memory unavaliable execption handler

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: default avatarMatt Evans <matt@ozlabs.org>
Signed-off-by: default avatarMichael Neuling <mikey@neuling.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent fb09692e
...@@ -336,6 +336,11 @@ vsx_unavailable_pSeries_1: ...@@ -336,6 +336,11 @@ vsx_unavailable_pSeries_1:
EXCEPTION_PROLOG_0(PACA_EXGEN) EXCEPTION_PROLOG_0(PACA_EXGEN)
b vsx_unavailable_pSeries b vsx_unavailable_pSeries
. = 0xf60
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_0(PACA_EXGEN)
b tm_unavailable_pSeries
#ifdef CONFIG_CBE_RAS #ifdef CONFIG_CBE_RAS
STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202) KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
...@@ -550,6 +555,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206) ...@@ -550,6 +555,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20) KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20)
STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable) STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40) 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: * An interrupt came in while soft-disabled. We set paca->irq_happened, then:
...@@ -852,6 +859,12 @@ vsx_unavailable_relon_pSeries_1: ...@@ -852,6 +859,12 @@ vsx_unavailable_relon_pSeries_1:
EXCEPTION_PROLOG_0(PACA_EXGEN) EXCEPTION_PROLOG_0(PACA_EXGEN)
b vsx_unavailable_relon_pSeries 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) STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint)
#ifdef CONFIG_PPC_DENORMALISATION #ifdef CONFIG_PPC_DENORMALISATION
. = 0x5500 . = 0x5500
...@@ -1201,6 +1214,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) ...@@ -1201,6 +1214,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
bl .vsx_unavailable_exception bl .vsx_unavailable_exception
b .ret_from_except 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 .align 7
.globl __end_handlers .globl __end_handlers
__end_handlers: __end_handlers:
...@@ -1220,6 +1242,7 @@ __end_handlers: ...@@ -1220,6 +1242,7 @@ __end_handlers:
STD_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor) STD_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable) STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_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) #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
/* /*
......
...@@ -1168,6 +1168,27 @@ void vsx_unavailable_exception(struct pt_regs *regs) ...@@ -1168,6 +1168,27 @@ void vsx_unavailable_exception(struct pt_regs *regs)
die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT); 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) void performance_monitor_exception(struct pt_regs *regs)
{ {
__get_cpu_var(irq_stat).pmu_irqs++; __get_cpu_var(irq_stat).pmu_irqs++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment