diff options
| author | Loic Prylli <lprylli@netflix.com> | 2025-10-06 17:59:41 +0000 |
|---|---|---|
| committer | Jonathan T. Looney <jtl@FreeBSD.org> | 2025-10-07 16:36:47 +0000 |
| commit | 1c2fc62e4a9689961169be7836038acd5f757be1 (patch) | |
| tree | a380d6b54c311a37a3b3aa99e9559e2be7994b72 | |
| parent | 1b0fce2944e3ff570b11de05c6a03977ee5b95e6 (diff) | |
x86: Add a way to inject artificial MCA events for testing
Reviewed by: glebius
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D52942
| -rw-r--r-- | sys/x86/x86/mca.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/sys/x86/x86/mca.c b/sys/x86/x86/mca.c index 7ee22895e0a7..4b40f343ac90 100644 --- a/sys/x86/x86/mca.c +++ b/sys/x86/x86/mca.c @@ -124,6 +124,17 @@ SYSCTL_INT(_hw_mca, OID_AUTO, erratum383, CTLFLAG_RDTUN, &workaround_erratum383, 0, "Is the workaround for Erratum 383 on AMD Family 10h processors enabled?"); +#ifdef DIAGNOSTIC +static uint64_t fake_status; +SYSCTL_U64(_hw_mca, OID_AUTO, fake_status, CTLFLAG_RW, + &fake_status, 0, + "Insert artificial MCA with given status (testing purpose only)"); +static int fake_bank; +SYSCTL_INT(_hw_mca, OID_AUTO, fake_bank, CTLFLAG_RW, + &fake_bank, 0, + "Bank to use for artificial MCAs (testing purpose only)"); +#endif + static STAILQ_HEAD(, mca_internal) mca_freelist; static int mca_freecount; static STAILQ_HEAD(, mca_internal) mca_records; @@ -701,8 +712,24 @@ mca_check_status(enum scan_mode mode, uint64_t mcg_cap, int bank, bool mce, recover; status = rdmsr(mca_msr_ops.status(bank)); - if (!(status & MC_STATUS_VAL)) + if (!(status & MC_STATUS_VAL)) { +#ifdef DIAGNOSTIC + /* + * Check if we have a pending artificial event to generate. + * Note that this is potentially racy with the sysctl. The + * tradeoff is deemed acceptable given the test nature + * of the code. + */ + if (fake_status && bank == fake_bank) { + status = fake_status; + fake_status = 0; + } + if (!(status & MC_STATUS_VAL)) + return (0); +#else return (0); +#endif + } recover = *recoverablep; mce = mca_is_mce(mcg_cap, status, &recover); |
