mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
x86/mca: MCA bank clear
1). Add explicitly uc=pcc=1 fatal error detect, since under such case the s/ar/over bits status is undefined and hence may be mis-cleaned. Explicit fatal detect return 0 indicate stick MSR bank will have chance to be handled after reboot by polling; 2). Fix a little bug for case SRAR, over bit should be 0 when need clear bank, otherwise it would reset system; 3). When clear bank, add clear MCi_ADDR/MISC if it's valid, according to Intel SDM; Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
This commit is contained in:
1 parent
89a4be6901
commit
d6c52e8a40
2 files changed
+31
-12
No files matched your search
@@ -135,6 +135,21 @@ void mcabanks_free(struct mca_banks *banks)
|
||||
xfree(banks->bank_map);
|
||||
xfree(banks);
|
||||
}
|
||||
|
||||
static void mcabank_clear(int banknum)
|
||||
{
|
||||
uint64_t status;
|
||||
|
||||
status = mca_rdmsr(MSR_IA32_MCx_STATUS(banknum));
|
||||
|
||||
if (status & MCi_STATUS_ADDRV)
|
||||
mca_wrmsr(MSR_IA32_MCx_ADDR(banknum), 0x0ULL);
|
||||
if (status & MCi_STATUS_MISCV)
|
||||
mca_wrmsr(MSR_IA32_MCx_MISC(banknum), 0x0ULL);
|
||||
|
||||
mca_wrmsr(MSR_IA32_MCx_STATUS(banknum), 0x0ULL);
|
||||
}
|
||||
|
||||
/* Judging whether to Clear Machine Check error bank callback handler
|
||||
* According to Intel latest MCA OS Recovery Writer's Guide,
|
||||
* whether the error MCA bank needs to be cleared is decided by the mca_source
|
||||
@@ -345,8 +360,8 @@ mctelem_cookie_t mcheck_mca_logout(enum mca_source who, struct mca_banks *bankma
|
||||
|
||||
/* By default, need_clear = 1 */
|
||||
if (who != MCA_MCE_SCAN && need_clear)
|
||||
/* Clear status */
|
||||
mca_wrmsr(MSR_IA32_MCx_STATUS(i), 0x0ULL);
|
||||
/* Clear bank */
|
||||
mcabank_clear(i);
|
||||
else if ( who == MCA_MCE_SCAN && need_clear)
|
||||
mcabanks_set(i, clear_bank);
|
||||
|
||||
@@ -601,15 +616,11 @@ void mcheck_cmn_handler(struct cpu_user_regs *regs, long error_code,
|
||||
void mcheck_mca_clearbanks(struct mca_banks *bankmask)
|
||||
{
|
||||
int i;
|
||||
uint64_t status;
|
||||
|
||||
for (i = 0; i < 32 && i < nr_mce_banks; i++) {
|
||||
for (i = 0; i < nr_mce_banks; i++) {
|
||||
if (!mcabanks_test(i, bankmask))
|
||||
continue;
|
||||
status = mca_rdmsr(MSR_IA32_MCx_STATUS(i));
|
||||
if (!(status & MCi_STATUS_VAL))
|
||||
continue;
|
||||
mca_wrmsr(MSR_IA32_MCx_STATUS(i), 0x0ULL);
|
||||
mcabank_clear(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -903,17 +903,25 @@ static int intel_need_clearbank_scan(enum mca_source who, u64 status)
|
||||
else return 0;
|
||||
}
|
||||
else if ( who == MCA_MCE_SCAN) {
|
||||
if ( !ser_support )
|
||||
return 0;
|
||||
/*
|
||||
* For fatal error, it shouldn't be cleared so that sticky bank
|
||||
* have chance to be handled after reboot by polling
|
||||
*/
|
||||
if ( (status & MCi_STATUS_UC) && (status & MCi_STATUS_PCC) )
|
||||
return 0;
|
||||
/* Spurious need clear bank */
|
||||
if ( ser_support && !(status & MCi_STATUS_OVER)
|
||||
else if ( !(status & MCi_STATUS_OVER)
|
||||
&& (status & MCi_STATUS_UC) && !(status & MCi_STATUS_EN))
|
||||
return 1;
|
||||
/* SRAR OVER=0 clear bank. OVER = 1 have caused reset */
|
||||
else if ( ser_support && (status & MCi_STATUS_UC)
|
||||
else if ( (status & MCi_STATUS_UC)
|
||||
&& (status & MCi_STATUS_S) && (status & MCi_STATUS_AR )
|
||||
&& (status & MCi_STATUS_OVER) )
|
||||
&& !(status & MCi_STATUS_OVER) )
|
||||
return 1;
|
||||
/* SRAO need clear bank */
|
||||
else if ( ser_support && !(status & MCi_STATUS_AR)
|
||||
else if ( !(status & MCi_STATUS_AR)
|
||||
&& (status & MCi_STATUS_S) && (status & MCi_STATUS_UC))
|
||||
return 1;
|
||||
else
|
||||
|
||||