static int convert_log(struct mc_info *mi) { struct mcinfo_common *mic = NULL; struct mcinfo_global *mc_global; struct mcinfo_bank *mc_bank; struct mce m; unsigned int i; bool found = false; x86_mcinfo_lookup(mic, mi, MC_TYPE_GLOBAL); if (mic == NULL) { printk(KERN_ERR "DOM0_MCE_LOG: global data is NULL\n"); return -1; } mce_setup(&m); mc_global = (struct mcinfo_global*)mic; m.mcgstatus = mc_global->mc_gstatus; m.apicid = mc_global->mc_apicid; for (i = 0; i < ncpus; i++) if (g_physinfo[i].mc_apicid == m.apicid) { found = true; break; } WARN_ON_ONCE(!found); m.socketid = g_physinfo[i].mc_chipid; m.cpu = m.extcpu = g_physinfo[i].mc_cpunr; m.cpuvendor = (__u8)g_physinfo[i].mc_vendor; x86_mcinfo_lookup(mic, mi, MC_TYPE_BANK); do { if (mic == NULL || mic->size == 0) break; if (mic->type == MC_TYPE_BANK) { mc_bank = (struct mcinfo_bank*)mic; m.misc = mc_bank->mc_misc; m.status = mc_bank->mc_status; m.addr = mc_bank->mc_addr; m.tsc = mc_bank->mc_tsc; m.bank = mc_bank->mc_bank; printk(KERN_DEBUG "[CPU%d, BANK%d, addr %llx, state %llx]\n", m.bank, m.cpu, m.addr, m.status); /*log this record*/ mce_log(&m); } mic = x86_mcinfo_next(mic); }while (1); return 0; }
void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err) { struct mce m; /* Only corrected MC is reported */ if (!corrected || !(mem_err->validation_bits & CPER_MEM_VALID_PA)) return; mce_setup(&m); m.bank = 1; /* Fake a memory read corrected error with unknown channel */ m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | 0x9f; m.addr = mem_err->physical_addr; mce_log(&m); mce_notify_irq(); }