If the kernel disables transactional memory (TM) and userspace still tries TM related actions (TM instructions or TM SPR accesses) TM aware hardware will cause the kernel to take a facility unavailable exception.
Add checks for the exception being caused by illegal TM access in userspace. Signed-off-by: Cyril Bur <cyril...@gmail.com> --- arch/powerpc/kernel/traps.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 0eba74b..cd40130 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1372,6 +1372,13 @@ void vsx_unavailable_exception(struct pt_regs *regs) } #ifdef CONFIG_PPC64 +static void tm_unavailable(struct pt_regs *regs) +{ + pr_emerg("Unrecoverable TM Unavailable Exception " + "%lx at %lx\n", regs->trap, regs->nip); + die("Unrecoverable TM Unavailable Exception", regs, SIGABRT); +} + void facility_unavailable_exception(struct pt_regs *regs) { static char *facility_strings[] = { @@ -1451,6 +1458,23 @@ void facility_unavailable_exception(struct pt_regs *regs) return; } + /* + * TM Unavailable + * + * If + * - firmware bits say don't do TM or + * - CONFIG_PPC_TRANSACTIONAL_MEM was not set and + * - hardware is actually TM aware + * Then userspace can spam the console (even with the use of + * _ratelimited), just send the SIGILL. + */ + if (status == FSCR_TM_LG) { + if (!cpu_has_feature(CPU_FTR_TM)) + goto out; + tm_unavailable(regs); + return; + } + if ((status < ARRAY_SIZE(facility_strings)) && facility_strings[status]) facility = facility_strings[status]; @@ -1463,6 +1487,7 @@ void facility_unavailable_exception(struct pt_regs *regs) "%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n", hv ? "Hypervisor " : "", facility, regs->nip, regs->msr); +out: if (user_mode(regs)) { _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); return; -- 2.9.3