Currently, the total AMD node count is determined by searching and counting CPU/node devices using PCI IDs. However, AMD node information is already available through topology CPUID/MSRs. The recent topology rework has made this info easier to access. Replace the node counting code with a simple product of topology info. Every node/northbridge is expected to have a 'misc' device. Clear everything out if a 'misc' device isn't found on a node. Signed-off-by: Yazen Ghannam <yazen.ghannam@xxxxxxx> Signed-off-by: Borislav Petkov (AMD) <bp@xxxxxxxxx> Link: https://lore.kernel.org/r/20241206161210.163701-8-yazen.ghannam@xxxxxxx --- arch/x86/include/asm/amd_node.h | 5 +++++ arch/x86/kernel/amd_nb.c | 22 +++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/amd_node.h b/arch/x86/include/asm/amd_node.h index 3f097dd479f8..419a0ad13ef2 100644 --- a/arch/x86/include/asm/amd_node.h +++ b/arch/x86/include/asm/amd_node.h @@ -25,4 +25,9 @@ struct pci_dev *amd_node_get_func(u16 node, u8 func); struct pci_dev *amd_node_get_root(u16 node); +static inline u16 amd_num_nodes(void) +{ + return topology_amd_nodes_per_pkg() * topology_max_packages(); +} + #endif /*_ASM_X86_AMD_NODE_H_*/ diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 6218a0428c77..6371fe96b988 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -186,7 +186,6 @@ static int amd_cache_northbridges(void) const struct pci_device_id *misc_ids = amd_nb_misc_ids; struct pci_dev *misc; struct amd_northbridge *nb; - u16 misc_count = 0; u16 i; if (amd_northbridges.num) @@ -196,25 +195,30 @@ static int amd_cache_northbridges(void) misc_ids = hygon_nb_misc_ids; } - misc = NULL; - while ((misc = next_northbridge(misc, misc_ids))) - misc_count++; - - if (!misc_count) - return -ENODEV; + amd_northbridges.num = amd_num_nodes(); - nb = kcalloc(misc_count, sizeof(struct amd_northbridge), GFP_KERNEL); + nb = kcalloc(amd_northbridges.num, sizeof(struct amd_northbridge), GFP_KERNEL); if (!nb) return -ENOMEM; amd_northbridges.nb = nb; - amd_northbridges.num = misc_count; misc = NULL; for (i = 0; i < amd_northbridges.num; i++) { node_to_amd_nb(i)->root = amd_node_get_root(i); node_to_amd_nb(i)->misc = misc = next_northbridge(misc, misc_ids); + + /* + * Each Northbridge must have a 'misc' device. + * If not, then uninitialize everything. + */ + if (!node_to_amd_nb(i)->misc) { + amd_northbridges.num = 0; + kfree(nb); + return -ENODEV; + } + node_to_amd_nb(i)->link = amd_node_get_func(i, 4); } -- 2.43.0