* [PATCH] x86/mce/amd: Don't poll unpopulated SMCA banks
@ 2026-11-07 11:12 Zak Brighton Knight
2026-11-09 19:20 ` Yazen Ghannam
0 siblings, 1 reply; 2+ messages in thread
From: Zak Brighton Knight @ 2026-11-07 11:12 UTC (permalink / raw)
To: Tony Luck, Borislav Petkov, linux-edac
Cc: Yazen Ghannam, Thomas Gleixner, Ingo Molnar, Dave Hansen, x86,
H. Peter Anvin, linux-kernel, Zak Brighton Knight
On a Ryzen 9 5900X (family 19h model 21h) the kernel logs a bogus
"System Fatal error" every week or two. It always comes from CPU 1 and
from a bank that CPU doesn't have.
mce: [Hardware Error]: Machine check events logged
[Hardware Error]: System Fatal error.
[Hardware Error]: CPU:1 (19:21:2) MC14_STATUS[Over|UE|MiscV|AddrV|PCC|SyndV|UECC|Deferred|Poison|Scrub]: 0xffffffff8b416928
[Hardware Error]: Error Addr: 0x0000000000000000
[Hardware Error]: IPID: 0x0000000000000000, Syndrome: 0x0000000000000000
[Hardware Error]: Bank 14 is reserved.
[Hardware Error]: cache level: RESV, tx: GEN
On this system only CPU 0 has the shared banks like L3, UMC and PSP. On
every other CPU banks 4 and 7-27 are unpopulated. Their MCA_IPID reads
as zero and their MCA_CTL doesn't keep the value written to it. So
__mcheck_cpu_init_prepare_banks() marks them as not initialized. But
their ctl stays at the default of all ones. machine_check_poll() still
reads their MCA_STATUS on every poll and smca_should_log_poll_error()
reads their MCA_DESTAT.
On CPU 1 these reads now and then return a non-zero value. The values
look like memory contents rather than error status. They include kernel
page table entries (0x8000000100c0d163), x86 instruction bytes
(0x900000000000841f) and kernel pointers. When bit 63 happens to be set
the value passes the MCI_STATUS_VAL check. It is then logged as an
uncorrected error with nearly every status bit set. This machine logged
39 of them between July 2025 and October 2026 on kernels 6.15 to 7.2.
All of them came from CPU 1 and from unpopulated banks. Users of other
Zen3 desktop parts (5800X, 5800X3D and 5950X) report the same signature.
For them it also always comes from CPU 1.
Commit 0422b07bc4c2 ("x86/mce/amd: Filter bogus hardware errors on Zen3
clients") filters a related signature but only on Cezanne A0.
An unpopulated bank has no hardware behind it and nothing to poll. In
smca_configure() clear the ctl of any bank whose MCA_IPID hardware ID
and MCA type are both zero. machine_check_poll() and __mc_scan_banks()
then skip it like any other disabled bank.
An AI coding assistant (Claude by Anthropic) helped find the cause and
draft this patch.
Signed-off-by: Zak Brighton Knight <zakbrightonknight@gmail.com>
Cc: stable@vger.kernel.org
---
I tested this on a Ryzen 9 5900X (MSI MAG X570S Tomahawk Max WiFi with
microcode 0x0a201213). I set check_interval to 1 so the banks are polled
every second instead of every five minutes. That way the bogus records
turn up within hours rather than weeks.
- Fedora's 7.2.11 on BIOS 1.B0 logged 34 bogus records in 22 hours.
All came from CPU 1 and from 16 different unpopulated banks. Nothing
else was logged.
- Fedora's 7.2.13 with the same change logged none in 8 hours 10
minutes on BIOS 1.B0. The unpatched rate predicts about 12.5. The
7.2 code around the change still uses the 32-bit MSR helpers but the
change itself is the same.
- Fedora's 7.2.13 without the change still logged 14 in 21.5 hours
after I updated to the latest BIOS (1.D3 with the same microcode).
So the firmware update doesn't fix it.
This version against tip master builds without warnings with W=1. I have
only booted the 7.2.13 version.
Reading the unpopulated banks directly through /dev/cpu/*/msr shows the
same thing. CPU 1 returns a non-zero value about once in 1.6 to 6.8
million reads. It does so on both BIOS versions and under the patched
kernel too. No other CPU ever did in over 250 million reads. So the
clean run is down to the patch and not to quieter hardware.
One boot of the patched kernel ended after 17 minutes in a hardware
reset (a data fabric sync flood). The MCE kept across the reset is an EX
watchdog timeout on CPU 16. Its address most likely points at the WRMSR
in native_write_msr(). I don't think it's related because the patch only
changes which banks get read. The next boot of the same kernel ran 13
hours without trouble. I mention it for completeness.
There is no Fixes: tag because every bank up to MCG_CAP[Count] has been
polled since long before SMCA. The closest candidates are two commits.
d9d73fcc8784 ("x86/mce: Detect and use SMCA-specific msr_ops") started
polling the SMCA registers. 068b053dca0e ("x86/MCE: Determine MCA banks'
init state properly") marked these banks as not initialized but kept
polling them. Happy to add either.
mce_no_way_out() still reads every bank whatever its ctl. So junk there
during a real #MC on CPU 1 could still escalate it to a panic. I left
that alone. It could skip banks with a ctl of 0 too if you prefer.
I don't know why only CPU 1 (APIC ID 2) does this on every Zen3 desktop
part reported so far.
Other users report the same signature in these threads.
https://forum.proxmox.com/threads/ryzen-5950x-uncorrected-software-containable-error-events-after-upgrade-to-kernel-7-0-x.184025/
https://discussion.fedoraproject.org/t/hardware-errors/193072
https://bbs.archlinux.org/viewtopic.php?id=304584
https://github.com/8do-abehn/lab/issues/435
I used Claude Code to help triage and write the patch.
arch/x86/kernel/cpu/mce/amd.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index 1cc20b855..1de43386c 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -345,6 +345,15 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
hwid_mcatype = HWID_MCATYPE(val.h & MCI_IPID_HWID,
(val.h & MCI_IPID_MCATYPE) >> 16);
+ /*
+ * An unpopulated bank has no hardware behind it and nothing to
+ * poll or scan. Its registers should read as zero. But on some
+ * Zen3 parts MCA_STATUS and MCA_DESTAT can return garbage that
+ * would then be logged as an error.
+ */
+ if (!hwid_mcatype)
+ this_cpu_ptr(mce_banks_array)[bank].ctl = 0;
+
for (i = 0; i < ARRAY_SIZE(smca_hwid_mcatypes); i++) {
s_hwid = &smca_hwid_mcatypes[i];
base-commit: 4f08fc2dfebccc28b7a7645dd81d28a755815e47
--
2.56.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] x86/mce/amd: Don't poll unpopulated SMCA banks
2026-11-07 11:12 [PATCH] x86/mce/amd: Don't poll unpopulated SMCA banks Zak Brighton Knight
@ 2026-11-09 19:20 ` Yazen Ghannam
0 siblings, 0 replies; 2+ messages in thread
From: Yazen Ghannam @ 2026-11-09 19:20 UTC (permalink / raw)
To: Zak Brighton Knight
Cc: Tony Luck, Borislav Petkov, linux-edac, Thomas Gleixner,
Ingo Molnar, Dave Hansen, x86, H. Peter Anvin, linux-kernel
On Sat, Nov 07, 2026 at 11:12:11AM +0000, Zak Brighton Knight wrote:
Hi Zak,
Thanks for the patch.
> On a Ryzen 9 5900X (family 19h model 21h) the kernel logs a bogus
> "System Fatal error" every week or two. It always comes from CPU 1 and
> from a bank that CPU doesn't have.
>
> mce: [Hardware Error]: Machine check events logged
> [Hardware Error]: System Fatal error.
> [Hardware Error]: CPU:1 (19:21:2) MC14_STATUS[Over|UE|MiscV|AddrV|PCC|SyndV|UECC|Deferred|Poison|Scrub]: 0xffffffff8b416928
> [Hardware Error]: Error Addr: 0x0000000000000000
> [Hardware Error]: IPID: 0x0000000000000000, Syndrome: 0x0000000000000000
> [Hardware Error]: Bank 14 is reserved.
> [Hardware Error]: cache level: RESV, tx: GEN
>
> On this system only CPU 0 has the shared banks like L3, UMC and PSP. On
> every other CPU banks 4 and 7-27 are unpopulated. Their MCA_IPID reads
> as zero and their MCA_CTL doesn't keep the value written to it. So
> __mcheck_cpu_init_prepare_banks() marks them as not initialized. But
> their ctl stays at the default of all ones. machine_check_poll() still
> reads their MCA_STATUS on every poll and smca_should_log_poll_error()
> reads their MCA_DESTAT.
>
> On CPU 1 these reads now and then return a non-zero value. The values
> look like memory contents rather than error status. They include kernel
> page table entries (0x8000000100c0d163), x86 instruction bytes
> (0x900000000000841f) and kernel pointers. When bit 63 happens to be set
> the value passes the MCI_STATUS_VAL check. It is then logged as an
> uncorrected error with nearly every status bit set. This machine logged
> 39 of them between July 2025 and October 2026 on kernels 6.15 to 7.2.
> All of them came from CPU 1 and from unpopulated banks. Users of other
> Zen3 desktop parts (5800X, 5800X3D and 5950X) report the same signature.
> For them it also always comes from CPU 1.
>
> Commit 0422b07bc4c2 ("x86/mce/amd: Filter bogus hardware errors on Zen3
> clients") filters a related signature but only on Cezanne A0.
>
> An unpopulated bank has no hardware behind it and nothing to poll. In
> smca_configure() clear the ctl of any bank whose MCA_IPID hardware ID
> and MCA type are both zero. machine_check_poll() and __mc_scan_banks()
> then skip it like any other disabled bank.
>
> An AI coding assistant (Claude by Anthropic) helped find the cause and
> draft this patch.
A lot of the commit message details can go in the notes below the cut.
IIUC, this would include the coding assistant info.
Here's another draft of the commit message:
"""""
By default, the MCE init code will attempt to set MCi_CTL for all MCA
banks on a CPU. This includes unused MCA banks which are read-as-zero
(RAZ) and writes-ignored (WI). The init code will check for this by
reading back the MCi_CTL register. If no bits are set, then the bank is
marked as "not initialized".
However, "not initialized" only applies to the MCE sysfs interface. The
bank's "ctl" value is still set, and this is checked in the MCE polling
functions.
Normally this is benign, since an unused bank would return '0' for
MCi_STATUS. But in some cases, the MCi_STATUS register will have a value
with the "Valid" bit set. And this results in logging bogus errors.
They're determined to be bogus based on the combination of status bits
set. Also, they are logged from MCA banks that have an MCA_IPID value of
'0', i.e. reserved/unused.
Clear a bank's "ctl" value during SMCA init for unused banks. This will
save an unnecessary MSR read during normal operation, and it will avoid
logging bogus error values that may be present on some systems.
"""""
>
> Signed-off-by: Zak Brighton Knight <zakbrightonknight@gmail.com>
> Cc: stable@vger.kernel.org
> ---
> I tested this on a Ryzen 9 5900X (MSI MAG X570S Tomahawk Max WiFi with
> microcode 0x0a201213). I set check_interval to 1 so the banks are polled
> every second instead of every five minutes. That way the bogus records
> turn up within hours rather than weeks.
>
> - Fedora's 7.2.11 on BIOS 1.B0 logged 34 bogus records in 22 hours.
> All came from CPU 1 and from 16 different unpopulated banks. Nothing
> else was logged.
> - Fedora's 7.2.13 with the same change logged none in 8 hours 10
> minutes on BIOS 1.B0. The unpatched rate predicts about 12.5. The
> 7.2 code around the change still uses the 32-bit MSR helpers but the
> change itself is the same.
> - Fedora's 7.2.13 without the change still logged 14 in 21.5 hours
> after I updated to the latest BIOS (1.D3 with the same microcode).
> So the firmware update doesn't fix it.
>
> This version against tip master builds without warnings with W=1. I have
> only booted the 7.2.13 version.
>
> Reading the unpopulated banks directly through /dev/cpu/*/msr shows the
> same thing. CPU 1 returns a non-zero value about once in 1.6 to 6.8
> million reads. It does so on both BIOS versions and under the patched
> kernel too. No other CPU ever did in over 250 million reads. So the
> clean run is down to the patch and not to quieter hardware.
>
> One boot of the patched kernel ended after 17 minutes in a hardware
> reset (a data fabric sync flood). The MCE kept across the reset is an EX
> watchdog timeout on CPU 16. Its address most likely points at the WRMSR
> in native_write_msr(). I don't think it's related because the patch only
> changes which banks get read. The next boot of the same kernel ran 13
> hours without trouble. I mention it for completeness.
>
> There is no Fixes: tag because every bank up to MCG_CAP[Count] has been
> polled since long before SMCA. The closest candidates are two commits.
> d9d73fcc8784 ("x86/mce: Detect and use SMCA-specific msr_ops") started
> polling the SMCA registers. 068b053dca0e ("x86/MCE: Determine MCA banks'
> init state properly") marked these banks as not initialized but kept
> polling them. Happy to add either.
>
> mce_no_way_out() still reads every bank whatever its ctl. So junk there
> during a real #MC on CPU 1 could still escalate it to a panic. I left
> that alone. It could skip banks with a ctl of 0 too if you prefer.
>
Yeah, that needs a good look.
> I don't know why only CPU 1 (APIC ID 2) does this on every Zen3 desktop
> part reported so far.
>
> Other users report the same signature in these threads.
> https://forum.proxmox.com/threads/ryzen-5950x-uncorrected-software-containable-error-events-after-upgrade-to-kernel-7-0-x.184025/
> https://discussion.fedoraproject.org/t/hardware-errors/193072
> https://bbs.archlinux.org/viewtopic.php?id=304584
> https://github.com/8do-abehn/lab/issues/435
>
> I used Claude Code to help triage and write the patch.
>
> arch/x86/kernel/cpu/mce/amd.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
> index 1cc20b855..1de43386c 100644
> --- a/arch/x86/kernel/cpu/mce/amd.c
> +++ b/arch/x86/kernel/cpu/mce/amd.c
> @@ -345,6 +345,15 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
> hwid_mcatype = HWID_MCATYPE(val.h & MCI_IPID_HWID,
> (val.h & MCI_IPID_MCATYPE) >> 16);
>
> + /*
> + * An unpopulated bank has no hardware behind it and nothing to
> + * poll or scan. Its registers should read as zero. But on some
> + * Zen3 parts MCA_STATUS and MCA_DESTAT can return garbage that
> + * would then be logged as an error.
> + */
I suggest dropping or simplifying this comment.
Something like "Skip init for unused banks"
> + if (!hwid_mcatype)
> + this_cpu_ptr(mce_banks_array)[bank].ctl = 0;
> +
> for (i = 0; i < ARRAY_SIZE(smca_hwid_mcatypes); i++) {
> s_hwid = &smca_hwid_mcatypes[i];
>
>
> base-commit: 4f08fc2dfebccc28b7a7645dd81d28a755815e47
> --
Besides the commit message and comment, this looks good to me
technically.
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
Thanks,
Yazen
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-09 19:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-07 11:12 [PATCH] x86/mce/amd: Don't poll unpopulated SMCA banks Zak Brighton Knight
2026-11-09 19:20 ` Yazen Ghannam
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®