[PATCH v1 1/2] x86/amd_node: avoid divide-by-zero in amd_smn_init() under Xen dom0

From: Penny Zheng

Date: Wed May 06 2026 - 01:56:36 EST


To prevent each dom0 vCPU from looking like an SMT sibling of another
vCPU, Xen synthesizes guest x2APIC IDs as vcpu_index * 2.
While the spacing every vCPU's APIC ID by 2 can therefore push the IDs
past the package-field boundary, making Linux see more packages than
the platform actually has. amd_num_nodes() inherits that inflated count,
so num_nodes can exceed num_roots (the number of AMD root complexes
discovered on the PCI bus). The subsequent

roots_per_node = num_roots / num_nodes;
... count % roots_per_node ...

then divides by zero in amd_smn_init().

Reject num_roots < num_nodes explicitly and bail out with -ENODEV.

Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
---
arch/x86/kernel/amd_node.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c
index 0be01725a2a4..c896060fe0df 100644
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -282,6 +282,18 @@ static int __init amd_smn_init(void)
return -ENODEV;

num_nodes = amd_num_nodes();
+
+ /*
+ * Xen dom0's synthetic APIC IDs may imply more nodes than host
+ * bridges visible in PCI config space. Bail out to avoid a
+ * divide-by-zero when later computing roots_per_node.
+ */
+ if (num_roots < num_nodes) {
+ pr_debug("AMD root count (%u) < node count (%u); skipping SMN init\n",
+ num_roots, num_nodes);
+ return -ENODEV;
+ }
+
amd_roots = kzalloc_objs(*amd_roots, num_nodes);
if (!amd_roots)
return -ENOMEM;
--
2.43.0