void get_mce_status() { int banks = 0; u64 cap = 0; u64 val = 0; int i = 0; printk("Enter:%s", __func__); rdmsrl(MSR_IA32_MCG_CAP, cap); banks = min_t(unsigned, MAX_NR_BANKS, cap & 0xff); printk("banks:%0x, cap:%0x\n", banks, cap); for (i = 0; i < banks; i++) { rdmsrl(MSR_IA32_MCx_STATUS(i), val); if(val & 0x8000000000000000) { //64bit printk("i = %d, status: val:%lx ", i, val); if(val & 0x0400000000000000) { //58bit rdmsrl(MSR_IA32_MCx_ADDR(i), val); printk("i=%d, addr: val:%lx", i, val); } if(val & 0x0800000000000000) { //58bit rdmsrl(MSR_IA32_MCx_MISC(i), val); printk("i=%d, misc: val:%lx ", i, val); } } } rdmsrl(MSR_IA32_MCG_STATUS, val); printk("mcg_status:%0x\n", val); printk("\n"); }
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); }
static struct mcinfo_bank *mca_init_bank(enum mca_source who, struct mc_info *mi, int bank) { struct mcinfo_bank *mib; uint64_t addr=0, misc = 0; if (!mi) return NULL; mib = x86_mcinfo_reserve(mi, sizeof(struct mcinfo_bank)); if (!mib) { mi->flags |= MCINFO_FLAGS_UNCOMPLETE; return NULL; } memset(mib, 0, sizeof (struct mcinfo_bank)); mib->mc_status = mca_rdmsr(MSR_IA32_MCx_STATUS(bank)); mib->common.type = MC_TYPE_BANK; mib->common.size = sizeof (struct mcinfo_bank); mib->mc_bank = bank; addr = misc = 0; if (mib->mc_status & MCi_STATUS_MISCV) mib->mc_misc = mca_rdmsr(MSR_IA32_MCx_MISC(bank)); if (mib->mc_status & MCi_STATUS_ADDRV) { mib->mc_addr = mca_rdmsr(MSR_IA32_MCx_ADDR(bank)); if (mfn_valid(paddr_to_pfn(mib->mc_addr))) { struct domain *d; d = maddr_get_owner(mib->mc_addr); if (d != NULL && (who == MCA_POLLER || who == MCA_CMCI_HANDLER)) mib->mc_domid = d->domain_id; } } if (who == MCA_CMCI_HANDLER) { mib->mc_ctrl2 = mca_rdmsr(MSR_IA32_MC0_CTL2 + bank); rdtscll(mib->mc_tsc); } return mib; }
static void mca_init_bank(enum mca_source who, struct mc_info *mi, int bank) { struct mcinfo_bank *mib; if (!mi) return; mib = x86_mcinfo_reserve(mi, sizeof(*mib)); if (!mib) { mi->flags |= MCINFO_FLAGS_UNCOMPLETE; return; } mib->mc_status = mca_rdmsr(MSR_IA32_MCx_STATUS(bank)); mib->common.type = MC_TYPE_BANK; mib->common.size = sizeof (struct mcinfo_bank); mib->mc_bank = bank; if (mib->mc_status & MCi_STATUS_MISCV) mib->mc_misc = mca_rdmsr(MSR_IA32_MCx_MISC(bank)); if (mib->mc_status & MCi_STATUS_ADDRV) mib->mc_addr = mca_rdmsr(MSR_IA32_MCx_ADDR(bank)); if ((mib->mc_status & MCi_STATUS_MISCV) && (mib->mc_status & MCi_STATUS_ADDRV) && (mc_check_addr(mib->mc_status, mib->mc_misc, MC_ADDR_PHYSICAL)) && (who == MCA_POLLER || who == MCA_CMCI_HANDLER) && (mfn_valid(paddr_to_pfn(mib->mc_addr)))) { struct domain *d; d = maddr_get_owner(mib->mc_addr); if (d) mib->mc_domid = d->domain_id; } if (who == MCA_CMCI_HANDLER) { mib->mc_ctrl2 = mca_rdmsr(MSR_IA32_MC0_CTL2 + bank); rdtscll(mib->mc_tsc); } }