]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/amd_nb: Use topology info to get AMD node count
authorYazen Ghannam <yazen.ghannam@amd.com>
Tue, 7 Jan 2025 22:28:41 +0000 (22:28 +0000)
committerBorislav Petkov (AMD) <bp@alien8.de>
Wed, 8 Jan 2025 09:49:20 +0000 (10:49 +0100)
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@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20250107222847.3300430-7-yazen.ghannam@amd.com
arch/x86/include/asm/amd_node.h
arch/x86/kernel/amd_nb.c

index 3f097dd479f8b8d5746ab0926b052dbcd2ec6523..419a0ad13ef271b9457c83bf13aa132925e6ee49 100644 (file)
@@ -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_*/
index 6218a0428c772b5305bc7adc5eeb395e74e1a87f..6371fe96b98867fbae8c982238310dee8bcd1231 100644 (file)
@@ -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);
        }