예제 #1
0
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();
}