@@ -121,8 +121,6 @@ mce_banks_t mce_banks_ce_disabled;
121121static struct work_struct mce_work ;
122122static struct irq_work mce_irq_work ;
123123
124- static void (* quirk_no_way_out )(int bank , struct mce * m , struct pt_regs * regs );
125-
126124/*
127125 * CPU/chipset specific EDAC code can register a notifier call here to print
128126 * MCE errors in a human-readable form.
@@ -814,6 +812,34 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
814812}
815813EXPORT_SYMBOL_GPL (machine_check_poll );
816814
815+ /*
816+ * During IFU recovery Sandy Bridge -EP4S processors set the RIPV and
817+ * EIPV bits in MCG_STATUS to zero on the affected logical processor (SDM
818+ * Vol 3B Table 15-20). But this confuses both the code that determines
819+ * whether the machine check occurred in kernel or user mode, and also
820+ * the severity assessment code. Pretend that EIPV was set, and take the
821+ * ip/cs values from the pt_regs that mce_gather_info() ignored earlier.
822+ */
823+ static void quirk_sandybridge_ifu (int bank , struct mce * m , struct pt_regs * regs )
824+ {
825+ if (bank != 0 )
826+ return ;
827+ if ((m -> mcgstatus & (MCG_STATUS_EIPV |MCG_STATUS_RIPV )) != 0 )
828+ return ;
829+ if ((m -> status & (MCI_STATUS_OVER |MCI_STATUS_UC |
830+ MCI_STATUS_EN |MCI_STATUS_MISCV |MCI_STATUS_ADDRV |
831+ MCI_STATUS_PCC |MCI_STATUS_S |MCI_STATUS_AR |
832+ MCACOD )) !=
833+ (MCI_STATUS_UC |MCI_STATUS_EN |
834+ MCI_STATUS_MISCV |MCI_STATUS_ADDRV |MCI_STATUS_S |
835+ MCI_STATUS_AR |MCACOD_INSTR ))
836+ return ;
837+
838+ m -> mcgstatus |= MCG_STATUS_EIPV ;
839+ m -> ip = regs -> ip ;
840+ m -> cs = regs -> cs ;
841+ }
842+
817843/*
818844 * Do a quick check if any of the events requires a panic.
819845 * This decides if we keep the events around or clear them.
@@ -830,8 +856,8 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
830856 continue ;
831857
832858 __set_bit (i , validp );
833- if (quirk_no_way_out )
834- quirk_no_way_out (i , m , regs );
859+ if (mce_flags . snb_ifu_quirk )
860+ quirk_sandybridge_ifu (i , m , regs );
835861
836862 m -> bank = i ;
837863 if (mce_severity (m , regs , mca_cfg .tolerant , & tmp , true) >= MCE_PANIC_SEVERITY ) {
@@ -1714,34 +1740,6 @@ static void __mcheck_cpu_check_banks(void)
17141740 }
17151741}
17161742
1717- /*
1718- * During IFU recovery Sandy Bridge -EP4S processors set the RIPV and
1719- * EIPV bits in MCG_STATUS to zero on the affected logical processor (SDM
1720- * Vol 3B Table 15-20). But this confuses both the code that determines
1721- * whether the machine check occurred in kernel or user mode, and also
1722- * the severity assessment code. Pretend that EIPV was set, and take the
1723- * ip/cs values from the pt_regs that mce_gather_info() ignored earlier.
1724- */
1725- static void quirk_sandybridge_ifu (int bank , struct mce * m , struct pt_regs * regs )
1726- {
1727- if (bank != 0 )
1728- return ;
1729- if ((m -> mcgstatus & (MCG_STATUS_EIPV |MCG_STATUS_RIPV )) != 0 )
1730- return ;
1731- if ((m -> status & (MCI_STATUS_OVER |MCI_STATUS_UC |
1732- MCI_STATUS_EN |MCI_STATUS_MISCV |MCI_STATUS_ADDRV |
1733- MCI_STATUS_PCC |MCI_STATUS_S |MCI_STATUS_AR |
1734- MCACOD )) !=
1735- (MCI_STATUS_UC |MCI_STATUS_EN |
1736- MCI_STATUS_MISCV |MCI_STATUS_ADDRV |MCI_STATUS_S |
1737- MCI_STATUS_AR |MCACOD_INSTR ))
1738- return ;
1739-
1740- m -> mcgstatus |= MCG_STATUS_EIPV ;
1741- m -> ip = regs -> ip ;
1742- m -> cs = regs -> cs ;
1743- }
1744-
17451743/* Add per CPU specific workarounds here */
17461744static int __mcheck_cpu_apply_quirks (struct cpuinfo_x86 * c )
17471745{
@@ -1815,7 +1813,7 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
18151813 cfg -> bootlog = 0 ;
18161814
18171815 if (c -> x86 == 6 && c -> x86_model == 45 )
1818- quirk_no_way_out = quirk_sandybridge_ifu ;
1816+ mce_flags . snb_ifu_quirk = 1 ;
18191817 }
18201818
18211819 if (c -> x86_vendor == X86_VENDOR_ZHAOXIN ) {
0 commit comments