Message ID | 1372146477-4338-3-git-send-email-michael@ellerman.id.au |
---|---|
State | Accepted, archived |
Commit | 021424a1fce335e05807fd770eb8e1da30a63eea |
Headers | show |
Hi Michael, On Tue, 25 Jun 2013 17:47:56 +1000 Michael Ellerman <michael@ellerman.id.au> wrote: > > -void tm_unavailable_exception(struct pt_regs *regs) > +void facility_unavailable_exception(struct pt_regs *regs) > { > + static char *facility_strings[] = { > + "FPU", > + "VMX/VSX", > + "DSCR", > + "PMU SPRs", > + "BHRB", > + "TM", > + "AT", > + "EBB", > + "TAR", > + }; Are the indexes into this array defined somewhere? If not, can we do that. Then, can we use explicit indexed initialisers for this array?
On Thu, Jun 27, 2013 at 02:05:39PM +1000, Stephen Rothwell wrote: > Hi Michael, > > On Tue, 25 Jun 2013 17:47:56 +1000 Michael Ellerman <michael@ellerman.id.au> wrote: > > > > -void tm_unavailable_exception(struct pt_regs *regs) > > +void facility_unavailable_exception(struct pt_regs *regs) > > { > > + static char *facility_strings[] = { > > + "FPU", > > + "VMX/VSX", > > + "DSCR", > > + "PMU SPRs", > > + "BHRB", > > + "TM", > > + "AT", > > + "EBB", > > + "TAR", > > + }; > > Are the indexes into this array defined somewhere? If not, can we do > that. Then, can we use explicit indexed initialisers for this array? I'm not sure I follow. The mapping is defined by the definition of the "Interruption Cause" field of the FSCR, section 6.2.10 of PowerISA v2.07. cheers
Hi Michael, On Fri, 28 Jun 2013 00:16:31 +1000 Michael Ellerman <michael@ellerman.id.au> wrote: > > On Thu, Jun 27, 2013 at 02:05:39PM +1000, Stephen Rothwell wrote: > > > > On Tue, 25 Jun 2013 17:47:56 +1000 Michael Ellerman <michael@ellerman.id.au> wrote: > > > > > > -void tm_unavailable_exception(struct pt_regs *regs) > > > +void facility_unavailable_exception(struct pt_regs *regs) > > > { > > > + static char *facility_strings[] = { > > > + "FPU", > > > + "VMX/VSX", > > > + "DSCR", > > > + "PMU SPRs", > > > + "BHRB", > > > + "TM", > > > + "AT", > > > + "EBB", > > > + "TAR", > > > + }; > > > > Are the indexes into this array defined somewhere? If not, can we do > > that. Then, can we use explicit indexed initialisers for this array? > > I'm not sure I follow. > > The mapping is defined by the definition of the "Interruption Cause" > field of the FSCR, section 6.2.10 of PowerISA v2.07. OK, so these numbers are externally defined: #define FSCR_INT_CAUSE_FPU 0 ... #define FSCR_INT_CAUSE_TAR 8 (or maybe an enum) static char *facility_strings[] = { [ FSCR_INT_CAUSE_FPU ] = "FPU", [ FSCR_INT_CAUSE_VMX_VSX ] = "VMX/VSX", [ FSCR_INT_CAUSE_DSCR ] = "DSCR", [ FSCR_INT_CAUSE_PMU_SPRs ] = "PMU SPRs", [ FSCR_INT_CAUSE_BHRB ] = "BHRB", [ FSCR_INT_CAUSE_TM ] = "TM", [ FSCR_INT_CAUSE_AT ] = "AT", [ FSCR_INT_CAUSE_EBB ] = "EBB", [ FSCR_INT_CAUSE_TAR ] = "TAR", }; Or something similar. Of course, then your code should cope with facility_strings[...] being NULL. This makes it very clear that these things are not just "made up" for your code.
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 6bd6763..d55a63c 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -341,10 +341,11 @@ vsx_unavailable_pSeries_1: EXCEPTION_PROLOG_0(PACA_EXGEN) b vsx_unavailable_pSeries +facility_unavailable_trampoline: . = 0xf60 SET_SCRATCH0(r13) EXCEPTION_PROLOG_0(PACA_EXGEN) - b tm_unavailable_pSeries + b facility_unavailable_pSeries #ifdef CONFIG_CBE_RAS STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) @@ -522,7 +523,7 @@ denorm_done: 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) + STD_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf60) /* @@ -829,11 +830,11 @@ vsx_unavailable_relon_pSeries_1: EXCEPTION_PROLOG_0(PACA_EXGEN) b vsx_unavailable_relon_pSeries -tm_unavailable_relon_pSeries_1: +facility_unavailable_relon_trampoline: . = 0x4f60 SET_SCRATCH0(r13) EXCEPTION_PROLOG_0(PACA_EXGEN) - b tm_unavailable_relon_pSeries + b facility_unavailable_relon_pSeries STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint) #ifdef CONFIG_PPC_DENORMALISATION @@ -1159,15 +1160,7 @@ 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 - DISABLE_INTS - addi r3,r1,STACK_FRAME_OVERHEAD - bl .tm_unavailable_exception - b .ret_from_except + STD_EXCEPTION_COMMON(0xf60, facility_unavailable, .facility_unavailable_exception) .align 7 .globl __end_handlers @@ -1180,7 +1173,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) + STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) /* diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index c0e5caf..2053bbd 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1282,25 +1282,42 @@ void vsx_unavailable_exception(struct pt_regs *regs) die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT); } -void tm_unavailable_exception(struct pt_regs *regs) +void facility_unavailable_exception(struct pt_regs *regs) { + static char *facility_strings[] = { + "FPU", + "VMX/VSX", + "DSCR", + "PMU SPRs", + "BHRB", + "TM", + "AT", + "EBB", + "TAR", + }; + char *facility; + u64 value; + + value = mfspr(SPRN_FSCR) >> 56; + /* 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 (value < ARRAY_SIZE(facility_strings)) + facility = facility_strings[value]; + else + facility = "unknown"; + + pr_err("Facility '%s' unavailable, exception at 0x%lx, MSR=%lx\n", + facility, regs->nip, regs->msr); if (user_mode(regs)) { _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); return; } - die("Unexpected TM unavailable exception", regs, SIGABRT); + die("Unexpected facility unavailable exception", regs, SIGABRT); } #ifdef CONFIG_PPC_TRANSACTIONAL_MEM