in mcelog.c [219:293]
static int convert_log(struct mc_info *mi)
{
struct mcinfo_common *mic;
struct mcinfo_global *mc_global;
struct mcinfo_bank *mc_bank;
struct xen_mce m;
unsigned int i, j;
mic = NULL;
x86_mcinfo_lookup(&mic, mi, MC_TYPE_GLOBAL);
if (unlikely(!mic)) {
pr_warn("Failed to find global error info\n");
return -ENODEV;
}
memset(&m, 0, sizeof(struct xen_mce));
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)
break;
if (unlikely(i == ncpus)) {
pr_warn("Failed to match cpu with apicid %d\n", m.apicid);
return -ENODEV;
}
m.socketid = g_physinfo[i].mc_chipid;
m.cpu = m.extcpu = g_physinfo[i].mc_cpunr;
m.cpuvendor = (__u8)g_physinfo[i].mc_vendor;
for (j = 0; j < g_physinfo[i].mc_nmsrvals; ++j)
switch (g_physinfo[i].mc_msrvalues[j].reg) {
case MSR_IA32_MCG_CAP:
m.mcgcap = g_physinfo[i].mc_msrvalues[j].value;
break;
case MSR_PPIN:
case MSR_AMD_PPIN:
m.ppin = g_physinfo[i].mc_msrvalues[j].value;
break;
}
mic = NULL;
x86_mcinfo_lookup(&mic, mi, MC_TYPE_BANK);
if (unlikely(!mic)) {
pr_warn("Fail to find bank error info\n");
return -ENODEV;
}
do {
if ((!mic) || (mic->size == 0) ||
(mic->type != MC_TYPE_GLOBAL &&
mic->type != MC_TYPE_BANK &&
mic->type != MC_TYPE_EXTENDED &&
mic->type != MC_TYPE_RECOVERY))
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;
m.finished = 1;
/*log this record*/
xen_mce_log(&m);
}
mic = x86_mcinfo_next(mic);
} while (1);
return 0;
}