powerpc: Don't use generic machine check parsing everywhere
PATCH 1/1 powerpc: Don't use generic machine check parsing everywhere
If a platform provide it's own machine check handler, assume that code will handle the reason parsing and reporting the error. The current default fall-though only makes sense on a few 32-bit platforms that lack individual handlers.
arch/powerpc/kernel/traps.c +30 -28
@@ -440,34 +440,36 @@ void machine_check_exception(struct pt_regs *regs)if (reason &MCSR_BUS_WRERR )printk ("Bus - Write Bus Error on buffered store or cache line push\n" );#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ -printk ("Machine check in kernel mode.\n" ); -printk ("Caused by (from SRR1=%lx): " , reason); -switch (reason &0x601F0000 ) { -case 0x80000 : -printk ("Machine check signal\n" ); -break ; -case 0 :/* for 601 */ -case 0x40000 : -case 0x140000 :/* 7450 MSS error and TEA */ -printk ("Transfer error ack signal\n" ); -break ; -case 0x20000 : -printk ("Data parity error signal\n" ); -break ; -case 0x10000 : -printk ("Address parity error signal\n" ); -break ; -case 0x20000000 : -printk ("L1 Data Cache error\n" ); -break ; -case 0x40000000 : -printk ("L1 Instruction Cache error\n" ); -break ; -case 0x00100000 : -printk ("L2 data cache parity error\n" ); -break ; -default : -printk ("Unknown values in msr\n" ); +if (!ppc_md.machine_check_exception) { +printk ("Machine check in kernel mode.\n" ); +printk ("Caused by (from SRR1=%lx): " , reason); +switch (reason &0x601F0000 ) { +case 0x80000 : +printk ("Machine check signal\n" ); +break ; +case 0 :/* for 601 */ +case 0x40000 : +case 0x140000 :/* 7450 MSS error and TEA */ +printk ("Transfer error ack signal\n" ); +break ; +case 0x20000 : +printk ("Data parity error signal\n" ); +break ; +case 0x10000 : +printk ("Address parity error signal\n" ); +break ; +case 0x20000000 : +printk ("L1 Data Cache error\n" ); +break ; +case 0x40000000 : +printk ("L1 Instruction Cache error\n" ); +break ; +case 0x00100000 : +printk ("L2 data cache parity error\n" ); +break ; +default : +printk ("Unknown values in msr\n" ); + } }#endif /* CONFIG_4xx */
Quoted 4 lines · Olof Johansson
If a platform provide it's own machine check handler, assume that code will handle the reason parsing and reporting the error. The current default fall-though only makes sense on a few 32-bit platforms that lack individual handlers.
Might be nice to put that code into a function of its own, called print_6xx_machine_check or something similar.
Paul.
PATCH 1/1 powerpc: Separate out legacy MCE parsers
[POWERPC] Separate out legacy MCE parsers
Move out the old-style exception parsers to a separate function, and don't call it on platforms that has a platform-specific handler.
It would make sense to move out the generic versions into their platforms instead, but that can be done gradually down the road.
---
Quoted 9 lines · Paul Mackerras
Quoted 4 lines · Olof Johansson
If a platform provide it's own machine check handler, assume that code will handle the reason parsing and reporting the error. The current default fall-though only makes sense on a few 32-bit platforms that lack individual handlers.
Might be nice to put that code into a function of its own, called
print_6xx_machine_checkor something similar.
See below. Any platform that doesn't set it's own MCE handler will call the generic one, which is at the moment just a fallback to the previous versions.
-Olof
arch/powerpc/kernel/traps.c +124 -116
@@ -324,14 +324,137 @@ static inline int check_io_access(struct pt_regs *regs)#define clear_single_step (regs) ((regs)->msr &= ~MSR_SE)#endif +static int generic_machine_check_exception (struct pt_regs *regs) +{ +unsigned long reason =get_mc_reason (regs); + +#if defined(CONFIG_4xx) && !defined(CONFIG_440A ) +if (reason &ESR_IMCP ) { +printk ("Instruction" ); +mtspr (SPRN_ESR , reason & ~ESR_IMCP ); + }else +printk ("Data" ); +printk (" machine check in kernel mode.\n" ); +#elif defined(CONFIG_440A ) +printk ("Machine check in kernel mode.\n" ); +if (reason &ESR_IMCP ){ +printk ("Instruction Synchronous Machine Check exception\n" ); +mtspr (SPRN_ESR , reason & ~ESR_IMCP ); + } +else { +u32 mcsr =mfspr (SPRN_MCSR ); +if (mcsr &MCSR_IB ) +printk ("Instruction Read PLB Error\n" ); +if (mcsr &MCSR_DRB ) +printk ("Data Read PLB Error\n" ); +if (mcsr &MCSR_DWB ) +printk ("Data Write PLB Error\n" ); +if (mcsr &MCSR_TLBP ) +printk ("TLB Parity Error\n" ); +if (mcsr &MCSR_ICP ){ +flush_instruction_cache (); +printk ("I-Cache Parity Error\n" ); + } +if (mcsr &MCSR_DCSP ) +printk ("D-Cache Search Parity Error\n" ); +if (mcsr &MCSR_DCFP ) +printk ("D-Cache Flush Parity Error\n" ); +if (mcsr &MCSR_IMPE ) +printk ("Machine Check exception is imprecise\n" ); + +/* Clear MCSR */ +mtspr (SPRN_MCSR , mcsr); + } +#elif defined (CONFIG_E500 ) +printk ("Machine check in kernel mode.\n" ); +printk ("Caused by (from MCSR=%lx): " , reason); + +if (reason &MCSR_MCP ) +printk ("Machine Check Signal\n" ); +if (reason &MCSR_ICPERR ) +printk ("Instruction Cache Parity Error\n" ); +if (reason &MCSR_DCP_PERR ) +printk ("Data Cache Push Parity Error\n" ); +if (reason &MCSR_DCPERR ) +printk ("Data Cache Parity Error\n" ); +if (reason &MCSR_BUS_IAERR ) +printk ("Bus - Instruction Address Error\n" ); +if (reason &MCSR_BUS_RAERR ) +printk ("Bus - Read Address Error\n" ); +if (reason &MCSR_BUS_WAERR ) +printk ("Bus - Write Address Error\n" ); +if (reason &MCSR_BUS_IBERR ) +printk ("Bus - Instruction Data Error\n" ); +if (reason &MCSR_BUS_RBERR ) +printk ("Bus - Read Data Bus Error\n" ); +if (reason &MCSR_BUS_WBERR ) +printk ("Bus - Read Data Bus Error\n" ); +if (reason &MCSR_BUS_IPERR ) +printk ("Bus - Instruction Parity Error\n" ); +if (reason &MCSR_BUS_RPERR ) +printk ("Bus - Read Parity Error\n" ); +#elif defined (CONFIG_E200 ) +printk ("Machine check in kernel mode.\n" ); +printk ("Caused by (from MCSR=%lx): " , reason); + +if (reason &MCSR_MCP ) +printk ("Machine Check Signal\n" ); +if (reason &MCSR_CP_PERR ) +printk ("Cache Push Parity Error\n" ); +if (reason &MCSR_CPERR ) +printk ("Cache Parity Error\n" ); +if (reason &MCSR_EXCP_ERR ) +printk ("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n" ); +if (reason &MCSR_BUS_IRERR ) +printk ("Bus - Read Bus Error on instruction fetch\n" ); +if (reason &MCSR_BUS_DRERR ) +printk ("Bus - Read Bus Error on data load\n" ); +if (reason &MCSR_BUS_WRERR ) +printk ("Bus - Write Bus Error on buffered store or cache line push\n" ); +#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ +printk ("Machine check in kernel mode.\n" ); +printk ("Caused by (from SRR1=%lx): " , reason); +switch (reason &0x601F0000 ) { +case 0x80000 : +printk ("Machine check signal\n" ); +break ; +case 0 :/* for 601 */ +case 0x40000 : +case 0x140000 :/* 7450 MSS error and TEA */ +printk ("Transfer error ack signal\n" ); +break ; +case 0x20000 : +printk ("Data parity error signal\n" ); +break ; +case 0x10000 : +printk ("Address parity error signal\n" ); +break ; +case 0x20000000 : +printk ("L1 Data Cache error\n" ); +break ; +case 0x40000000 : +printk ("L1 Instruction Cache error\n" ); +break ; +case 0x00100000 : +printk ("L2 data cache parity error\n" ); +break ; +default : +printk ("Unknown values in msr\n" ); + } +#endif /* CONFIG_4xx */ + +return 0 ; +} +void machine_check_exception (struct pt_regs *regs) {int recover =0 ; -unsigned long reason =get_mc_reason (regs);/* See if any machine dependent calls */ if (ppc_md.machine_check_exception) recover = ppc_md.machine_check_exception (regs); +else + recover =generic_machine_check_exception (regs);if (recover)return ;
@@ -356,121 +479,6 @@ void machine_check_exception(struct pt_regs *regs)if (check_io_access (regs))return ; -#if defined(CONFIG_4xx) && !defined(CONFIG_440A ) -if (reason &ESR_IMCP ) { -printk ("Instruction" ); -mtspr (SPRN_ESR , reason & ~ESR_IMCP ); - }else -printk ("Data" ); -printk (" machine check in kernel mode.\n" ); -#elif defined(CONFIG_440A ) -printk ("Machine check in kernel mode.\n" ); -if (reason &ESR_IMCP ){ -printk ("Instruction Synchronous Machine Check exception\n" ); -mtspr (SPRN_ESR , reason & ~ESR_IMCP ); - } -else { -u32 mcsr =mfspr (SPRN_MCSR ); -if (mcsr &MCSR_IB ) -printk ("Instruction Read PLB Error\n" ); -if (mcsr &MCSR_DRB ) -printk ("Data Read PLB Error\n" ); -if (mcsr &MCSR_DWB ) -printk ("Data Write PLB Error\n" ); -if (mcsr &MCSR_TLBP ) -printk ("TLB Parity Error\n" ); -if (mcsr &MCSR_ICP ){ -flush_instruction_cache (); -printk ("I-Cache Parity Error\n" ); - } -if (mcsr &MCSR_DCSP ) -printk ("D-Cache Search Parity Error\n" ); -if (mcsr &MCSR_DCFP ) -printk ("D-Cache Flush Parity Error\n" ); -if (mcsr &MCSR_IMPE ) -printk ("Machine Check exception is imprecise\n" ); - -/* Clear MCSR */ -mtspr (SPRN_MCSR , mcsr); - } -#elif defined (CONFIG_E500 ) -printk ("Machine check in kernel mode.\n" ); -printk ("Caused by (from MCSR=%lx): " , reason); - -if (reason &MCSR_MCP ) -printk ("Machine Check Signal\n" ); -if (reason &MCSR_ICPERR ) -printk ("Instruction Cache Parity Error\n" ); -if (reason &MCSR_DCP_PERR ) -printk ("Data Cache Push Parity Error\n" ); -if (reason &MCSR_DCPERR ) -printk ("Data Cache Parity Error\n" ); -if (reason &MCSR_BUS_IAERR ) -printk ("Bus - Instruction Address Error\n" ); -if (reason &MCSR_BUS_RAERR ) -printk ("Bus - Read Address Error\n" ); -if (reason &MCSR_BUS_WAERR ) -printk ("Bus - Write Address Error\n" ); -if (reason &MCSR_BUS_IBERR ) -printk ("Bus - Instruction Data Error\n" ); -if (reason &MCSR_BUS_RBERR ) -printk ("Bus - Read Data Bus Error\n" ); -if (reason &MCSR_BUS_WBERR ) -printk ("Bus - Read Data Bus Error\n" ); -if (reason &MCSR_BUS_IPERR ) -printk ("Bus - Instruction Parity Error\n" ); -if (reason &MCSR_BUS_RPERR ) -printk ("Bus - Read Parity Error\n" ); -#elif defined (CONFIG_E200 ) -printk ("Machine check in kernel mode.\n" ); -printk ("Caused by (from MCSR=%lx): " , reason); - -if (reason &MCSR_MCP ) -printk ("Machine Check Signal\n" ); -if (reason &MCSR_CP_PERR ) -printk ("Cache Push Parity Error\n" ); -if (reason &MCSR_CPERR ) -printk ("Cache Parity Error\n" ); -if (reason &MCSR_EXCP_ERR ) -printk ("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n" ); -if (reason &MCSR_BUS_IRERR ) -printk ("Bus - Read Bus Error on instruction fetch\n" ); -if (reason &MCSR_BUS_DRERR ) -printk ("Bus - Read Bus Error on data load\n" ); -if (reason &MCSR_BUS_WRERR ) -printk ("Bus - Write Bus Error on buffered store or cache line push\n" ); -#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ -printk ("Machine check in kernel mode.\n" ); -printk ("Caused by (from SRR1=%lx): " , reason); -switch (reason &0x601F0000 ) { -case 0x80000 : -printk ("Machine check signal\n" ); -break ; -case 0 :/* for 601 */ -case 0x40000 : -case 0x140000 :/* 7450 MSS error and TEA */ -printk ("Transfer error ack signal\n" ); -break ; -case 0x20000 : -printk ("Data parity error signal\n" ); -break ; -case 0x10000 : -printk ("Address parity error signal\n" ); -break ; -case 0x20000000 : -printk ("L1 Data Cache error\n" ); -break ; -case 0x40000000 : -printk ("L1 Instruction Cache error\n" ); -break ; -case 0x00100000 : -printk ("L2 data cache parity error\n" ); -break ; -default : -printk ("Unknown values in msr\n" ); - } -#endif /* CONFIG_4xx */ -if (debugger_fault_handler (regs))return ;die ("Machine check" , regs,SIGBUS );