FreeBSD/sys/x86/x86/mca.c
/*
 * This scans all the machine check banks of the current CPU to see if
 * there are any machine checks.  Any non-recoverable errors are
 * reported immediately via mca_log().  The current thread must be
 * pinned when this is called.  The 'mode' parameter indicates if we
 * are being called from the MC exception handler, the CMCI handler,
 * or the periodic poller.  In the MC exception case this function
 * returns true if the system is restartable.  Otherwise, it returns a
 * count of the number of valid MC records found.
 */
This scans all the machine check banks of the current CPU to see if
there are any machine checks.  Any non-recoverable errors are
reported immediately via mca_log().  The current thread must be
pinned when this is called.  The 'mode' parameter indicates if we
are being called from the MC exception handler, the CMCI handler,
or the periodic poller.  In the MC exception case this function
returns true if the system is restartable.  Otherwise, it returns a
count of the number of valid MC records found.
This scans all the machine check banks of the current CPU to see if there are any machine checks . Any non - recoverable errors are reported immediately via mca_log () . The current thread must be pinned when this is called . The ' mode ' parameter indicates if we are being called from the MC exception handler the CMCI handler or the periodic poller . In the MC exception case this function returns true if the system is restartable . Otherwise it returns a count of the number of valid MC records found .
static int
mca_scan(enum scan_mode mode)
{
	struct mca_record rec;
	uint64_t mcg_cap, ucmask;
	int count, i, recoverable, valid;
	count = 0;
	recoverable = 1;
	ucmask = MC_STATUS_UC | MC_STATUS_PCC;
	if (mode == MCE)
		ucmask |= MC_STATUS_OVER;
	mcg_cap = rdmsr(MSR_MCG_CAP);
	for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) {
#ifdef DEV_APIC
		if (mode == CMCI && !(PCPU_GET(cmci_mask) & 1 << i))
			continue;
#endif
		valid = mca_check_status(i, &rec);
		if (valid) {
			count++;
			if (rec.mr_status & ucmask) {
				recoverable = 0;
				mtx_lock_spin(&mca_lock);
				mca_log(&rec);
				mtx_unlock_spin(&mca_lock);
			}
			mca_record_entry(mode, &rec);
		}
#ifdef DEV_APIC
		if (PCPU_GET(cmci_mask) & 1 << i)
			cmci_update(mode, i, valid, &rec);
#endif
	}
	if (mode == POLLED)
		mca_fill_freelist();
	return (mode == MCE ? recoverable : count);
}
static int mca_scan ( enum scan_mode mode ) { struct mca_record rec ; uint64_t mcg_cap , ucmask ; int count , i , recoverable , valid ; count = 0 ; recoverable = 1 ; ucmask = MC_STATUS_UC | MC_STATUS_PCC ; if ( mode == MCE ) ucmask |= MC_STATUS_OVER ; mcg_cap = rdmsr ( MSR_MCG_CAP ) ; for ( i = 0 ; i < ( mcg_cap & MCG_CAP_COUNT ) ; i ++ ) { #ifdef DEV_APIC if ( mode == CMCI && ! ( PCPU_GET ( cmci_mask ) & 1 << i ) ) continue ; #endif valid = mca_check_status ( i , & rec ) ; if ( valid ) { count ++ ; if ( rec . mr_status & ucmask ) { recoverable = 0 ; mtx_lock_spin ( & mca_lock ) ; mca_log ( & rec ) ; mtx_unlock_spin ( & mca_lock ) ; } mca_record_entry ( mode , & rec ) ; } #ifdef DEV_APIC if ( PCPU_GET ( cmci_mask ) & 1 << i ) cmci_update ( mode , i , valid , & rec ) ; #endif } if ( mode == POLLED ) mca_fill_freelist ( ) ; return ( mode == MCE ? recoverable : count ) ; }
This scans all the machine check banks of the current CPU to see if
 there are any machine checks.
This scans all the machine check banks of the current CPU to see if there are any machine checks .
/* When handling a MCE#, treat the OVER flag as non-restartable. */ /*
		 * For a CMCI, only check banks this CPU is
		 * responsible for.
		 */ /*
		 * If this is a bank this CPU monitors via CMCI,
		 * update the threshold.
		 */