// SPDX-License-Identifier: GPL-2.0-only /* * Bridge between MCE and APEI * * On some machine, corrected memory errors are reported via APEI * generic hardware error source (GHES) instead of corrected Machine * Check. These corrected memory errors can be reported to user space * through /dev/mcelog via faking a corrected Machine Check, so that * the error memory page can be offlined by /sbin/mcelog if the error * count for one page is beyond the threshold. * * For fatal MCE, save MCE record into persistent storage via ERST, so * that the MCE record can be logged after reboot via ERST. * * Copyright 2010 Intel Corp. * Author: Huang Ying <ying.huang@intel.com>
*/
if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) return;
/* * Even if the ->validation_bits are set for address mask, * to be extra safe, check and reject an error radius '0', * and fall back to the default page size.
*/ if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK)
lsb = find_first_bit((void *)&mem_err->physical_addr_mask, PAGE_SHIFT); else
lsb = PAGE_SHIFT;
if (!boot_cpu_has(X86_FEATURE_SMCA)) return -EINVAL;
/* * The starting address of the register array extracted from BERT must * match with the first expected register in the register layout of * SMCA address space. This address corresponds to banks's MCA_STATUS * register. * * Match any MCi_STATUS register by turning off bank numbers.
*/ if ((ctx_info->msr_addr & MSR_AMD64_SMCA_MC0_STATUS) !=
MSR_AMD64_SMCA_MC0_STATUS) return -EINVAL;
/* * The number of registers in the register array is determined by * Register Array Size/8 as defined in UEFI spec v2.8, sec N.2.4.2.2. * Sanity-check registers array size.
*/
num_regs = ctx_info->reg_arr_size >> 3; if (!num_regs) return -EINVAL;
m = &err.m;
memset(&err, 0, sizeof(struct mce_hw_err));
mce_prep_record_common(m);
mce_prep_record_per_cpu(cpu, m);
m->bank = (ctx_info->msr_addr >> 4) & 0xFF;
/* * The SMCA register layout is fixed and includes 16 registers. * The end of the array may be variable, but the beginning is known. * Cap the number of registers to expected max (15).
*/ if (num_regs > 15)
num_regs = 15;
switch (num_regs) { /* MCA_SYND2 */ case 15:
err.vendor.amd.synd2 = *(i_mce + 14);
fallthrough; /* MCA_SYND1 */ case 14:
err.vendor.amd.synd1 = *(i_mce + 13);
fallthrough; /* MCA_MISC4 */ case 13: /* MCA_MISC3 */ case 12: /* MCA_MISC2 */ case 11: /* MCA_MISC1 */ case 10: /* MCA_DEADDR */ case 9: /* MCA_DESTAT */ case 8: /* reserved */ case 7: /* MCA_SYND */ case 6:
m->synd = *(i_mce + 5);
fallthrough; /* MCA_IPID */ case 5:
m->ipid = *(i_mce + 4);
fallthrough; /* MCA_CONFIG */ case 4: /* MCA_MISC0 */ case 3:
m->misc = *(i_mce + 2);
fallthrough; /* MCA_ADDR */ case 2:
m->addr = *(i_mce + 1);
fallthrough; /* MCA_STATUS */ case 1:
m->status = *i_mce;
}
/* Check whether there is record in ERST */ int apei_check_mce(void)
{ return erst_get_record_count();
}
int apei_clear_mce(u64 record_id)
{ return erst_clear(record_id);
}
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.0Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.