void mca_dump(void) { ia32_mcg_status_t status; mca_state_t *mca_state = current_cpu_datap()->cpu_mca_state; /* * Capture local MCA registers to per-cpu data. */ mca_save_state(mca_state); /* * Serialize in case of multiple simultaneous machine-checks. * Only the first caller is allowed to dump MCA registers, * other threads spin meantime. */ simple_lock(&mca_lock); if (mca_dump_state > CLEAR) { simple_unlock(&mca_lock); while (mca_dump_state == DUMPING) cpu_pause(); return; } mca_dump_state = DUMPING; simple_unlock(&mca_lock); /* * Report machine-check capabilities: */ kdb_printf( "Machine-check capabilities (cpu %d) 0x%016qx:\n", cpu_number(), ia32_mcg_cap.u64); mca_report_cpu_info(); kdb_printf( " %d error-reporting banks\n%s%s%s", mca_error_bank_count, IF(mca_control_MSR_present, " control MSR present\n"), IF(mca_threshold_status_present, " threshold-based error status present\n"), IF(mca_cmci_present, " extended corrected memory error handling present\n")); if (mca_extended_MSRs_present) kdb_printf( " %d extended MSRs present\n", mca_extended_MSRs_count); /* * Report machine-check status: */ status.u64 = rdmsr64(IA32_MCG_STATUS); kdb_printf( "Machine-check status 0x%016qx:\n%s%s%s", status.u64, IF(status.bits.ripv, " restart IP valid\n"), IF(status.bits.eipv, " error IP valid\n"), IF(status.bits.mcip, " machine-check in progress\n")); /* * Dump error-reporting registers: */ mca_dump_error_banks(mca_state); /* * Dump any extended machine state: */ if (mca_extended_MSRs_present) { if (cpu_mode_is64bit()) mca_dump_64bit_state(); else mca_dump_32bit_state(); } /* Update state to release any other threads. */ mca_dump_state = DUMPED; }
void mca_dump(void) { mca_state_t *mca_state = current_cpu_datap()->cpu_mca_state; uint64_t deadline; unsigned int i = 0; /* * Capture local MCA registers to per-cpu data. */ mca_save_state(mca_state); /* * Serialize: the first caller controls dumping MCA registers, * other threads spin meantime. */ simple_lock(&mca_lock); if (mca_dump_state > CLEAR) { simple_unlock(&mca_lock); while (mca_dump_state == DUMPING) cpu_pause(); return; } mca_dump_state = DUMPING; simple_unlock(&mca_lock); /* * Wait for all other hardware threads to save their state. * Or timeout. */ deadline = mach_absolute_time() + LockTimeOut; while (mach_absolute_time() < deadline && i < real_ncpus) { if (!cpu_datap(i)->cpu_mca_state->mca_is_saved) { cpu_pause(); continue; } i += 1; } /* * Report machine-check capabilities: */ kdb_printf( "Machine-check capabilities 0x%016qx:\n", ia32_mcg_cap.u64); mca_report_cpu_info(); kdb_printf( " %d error-reporting banks\n%s%s%s", mca_error_bank_count, IF(mca_control_MSR_present, " control MSR present\n"), IF(mca_threshold_status_present, " threshold-based error status present\n"), IF(mca_cmci_present, " extended corrected memory error handling present\n")); if (mca_extended_MSRs_present) kdb_printf( " %d extended MSRs present\n", mca_extended_MSRs_count); /* * Dump all processor state: */ for (i = 0; i < real_ncpus; i++) { mca_state_t *mcsp = cpu_datap(i)->cpu_mca_state; ia32_mcg_status_t status; kdb_printf("Processor %d: ", i); if (mcsp == NULL || mcsp->mca_is_saved == FALSE || mcsp->mca_mcg_status.u64 == 0) { kdb_printf("no machine-check status reported\n"); continue; } if (!mcsp->mca_is_valid) { kdb_printf("no valid machine-check state\n"); continue; } status = mcsp->mca_mcg_status; kdb_printf( "machine-check status 0x%016qx:\n%s%s%s", status.u64, IF(status.bits.ripv, " restart IP valid\n"), IF(status.bits.eipv, " error IP valid\n"), IF(status.bits.mcip, " machine-check in progress\n")); mca_cpu_dump_error_banks(mcsp); } /* * Dump any extended machine state: */ if (mca_extended_MSRs_present) { if (cpu_mode_is64bit()) mca_dump_64bit_state(); else mca_dump_32bit_state(); } /* Update state to release any other threads. */ mca_dump_state = DUMPED; }
void mca_dump(void) { mca_state_t *mca_state = current_cpu_datap()->cpu_mca_state; uint64_t deadline; unsigned int i = 0; /* * Capture local MCA registers to per-cpu data. */ mca_save_state(mca_state); /* * Serialize: the first caller controls dumping MCA registers, * other threads spin meantime. */ simple_lock(&mca_lock); if (mca_dump_state > CLEAR) { simple_unlock(&mca_lock); while (mca_dump_state == DUMPING) cpu_pause(); return; } mca_dump_state = DUMPING; simple_unlock(&mca_lock); /* * Wait for all other hardware threads to save their state. * Or timeout. */ deadline = mach_absolute_time() + LockTimeOut; while (mach_absolute_time() < deadline && i < real_ncpus) { if (!cpu_datap(i)->cpu_mca_state->mca_is_saved) { cpu_pause(); continue; } i += 1; } /* * Report machine-check capabilities: */ kdb_printf("Machine-check capabilities: 0x%016qx\n", ia32_mcg_cap.u64); mca_report_cpu_info(); kdb_printf(" %d error-reporting banks\n", mca_error_bank_count); /* * Dump all processor state: */ for (i = 0; i < real_ncpus; i++) { mca_state_t *mcsp = cpu_datap(i)->cpu_mca_state; ia32_mcg_status_t status; if (mcsp == NULL || mcsp->mca_is_saved == FALSE || mcsp->mca_mcg_status.u64 == 0 || !mcsp->mca_is_valid) { continue; } status = mcsp->mca_mcg_status; kdb_printf("Processor %d: IA32_MCG_STATUS: 0x%016qx\n", i, status.u64); mca_cpu_dump_error_banks(mcsp); } /* Update state to release any other threads. */ mca_dump_state = DUMPED; }