[PATCH 1/3] x86/mce/amd: Fix bank lookup in amd_mce_usable_address()

From: Yazen Ghannam

Date: Thu Sep 03 2026 - 10:35:07 EST


amd_mce_usable_address() reads the per-CPU smca_banks array at index
m->bank on the running CPU. The index is not checked, and the bank
belongs to m->extcpu, not to whichever CPU is decoding.

m->bank is unbounded here. apei_mce_report_mem_error() sets it to -1,
which is 255 in the u8 field, and apei_smca_report_x86_error() takes it
from a firmware BERT record. Both reach this function through the
decoder chain, which runs from a workqueue on any CPU. Bank counts
differ per CPU on SMCA systems. So the read can land past the end of
the array, or on a CPU where that bank means something else.

Use m->extcpu for both the bound and the lookup.

Fixes: 821f5fe4dbcb ("x86/mce: Add support for physical address valid bit")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Claude:claude-opus-5
Signed-off-by: Yazen Ghannam <yazen.ghannam@xxxxxxx>
---
arch/x86/kernel/cpu/mce/amd.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index f916fb4c5d13..e6542e00dc5a 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -837,7 +837,8 @@ bool amd_mce_usable_address(struct mce *m)
return false;
}

- if (this_cpu_ptr(smca_banks)[m->bank].paddrv)
+ if (m->bank < per_cpu(mce_num_banks, m->extcpu) &&
+ per_cpu(smca_banks, m->extcpu)[m->bank].paddrv)
return m->status & MCI_STATUS_PADDRV;

/* Check poison bit for all other bank types. */
--
2.43.0