@@ -121,8 +121,6 @@ mce_banks_t mce_banks_ce_disabled;
121
121
static struct work_struct mce_work ;
122
122
static struct irq_work mce_irq_work ;
123
123
124
- static void (* quirk_no_way_out )(int bank , struct mce * m , struct pt_regs * regs );
125
-
126
124
/*
127
125
* CPU/chipset specific EDAC code can register a notifier call here to print
128
126
* MCE errors in a human-readable form.
@@ -814,6 +812,34 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
814
812
}
815
813
EXPORT_SYMBOL_GPL (machine_check_poll );
816
814
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
+
817
843
/*
818
844
* Do a quick check if any of the events requires a panic.
819
845
* 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,
830
856
continue ;
831
857
832
858
__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 );
835
861
836
862
m -> bank = i ;
837
863
if (mce_severity (m , regs , mca_cfg .tolerant , & tmp , true) >= MCE_PANIC_SEVERITY ) {
@@ -1714,34 +1740,6 @@ static void __mcheck_cpu_check_banks(void)
1714
1740
}
1715
1741
}
1716
1742
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
-
1745
1743
/* Add per CPU specific workarounds here */
1746
1744
static int __mcheck_cpu_apply_quirks (struct cpuinfo_x86 * c )
1747
1745
{
@@ -1815,7 +1813,7 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
1815
1813
cfg -> bootlog = 0 ;
1816
1814
1817
1815
if (c -> x86 == 6 && c -> x86_model == 45 )
1818
- quirk_no_way_out = quirk_sandybridge_ifu ;
1816
+ mce_flags . snb_ifu_quirk = 1 ;
1819
1817
}
1820
1818
1821
1819
if (c -> x86_vendor == X86_VENDOR_ZHAOXIN ) {
0 commit comments