Skip to content

Commit

Permalink
x86/amd_nb: Add support for newer PCI topologies
Browse files Browse the repository at this point in the history
Add support for new processors which have multiple PCI root complexes
per data fabric/system management network interface.  If there are (N)
multiple PCI roots per DF/SMN interface, then the PCI roots are
redundant (as far as SMN/DF access goes).  For each DF/SMN interface:
map to the first available PCI root and skip the next N-1 PCI roots so
the following DF/SMN interface get mapped to a correct PCI root.

Ex:
DF/SMN 0 -> 60
	    40
	    20
	    00
DF/SMN 1 -> e0
	    c0
	    a0
	    80

Signed-off-by: Brian Woods <brian.woods@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
CC: Bjorn Helgaas <bhelgaas@google.com>
CC: Clemens Ladisch <clemens@ladisch.de>
CC: Guenter Roeck <linux@roeck-us.net>
CC: "H. Peter Anvin" <hpa@zytor.com>
CC: Ingo Molnar <mingo@redhat.com>
CC: Jean Delvare <jdelvare@suse.com>
CC: Jia Zhang <qianyue.zj@alibaba-inc.com>
CC: <linux-hwmon@vger.kernel.org>
CC: <linux-pci@vger.kernel.org>
CC: Pu Wen <puwen@hygon.cn>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: x86-ml <x86@kernel.org>
Link: http://lkml.kernel.org/r/20181106200754.60722-3-brian.woods@amd.com
  • Loading branch information
Woods, Brian authored and Borislav Petkov committed Nov 7, 2018
1 parent dedf7dc commit 556e4c6
Showing 1 changed file with 38 additions and 6 deletions.
44 changes: 38 additions & 6 deletions arch/x86/kernel/amd_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,10 @@ int amd_cache_northbridges(void)
const struct pci_device_id *root_ids = amd_root_ids;
struct pci_dev *root, *misc, *link;
struct amd_northbridge *nb;
u16 i = 0;
u16 roots_per_misc = 0;
u16 misc_count = 0;
u16 root_count = 0;
u16 i, j;

if (amd_northbridges.num)
return 0;
Expand All @@ -226,26 +229,55 @@ int amd_cache_northbridges(void)

misc = NULL;
while ((misc = next_northbridge(misc, misc_ids)) != NULL)
i++;
misc_count++;

if (!i)
if (!misc_count)
return -ENODEV;

nb = kcalloc(i, sizeof(struct amd_northbridge), GFP_KERNEL);
root = NULL;
while ((root = next_northbridge(root, root_ids)) != NULL)
root_count++;

if (root_count) {
roots_per_misc = root_count / misc_count;

/*
* There should be _exactly_ N roots for each DF/SMN
* interface.
*/
if (!roots_per_misc || (root_count % roots_per_misc)) {
pr_info("Unsupported AMD DF/PCI configuration found\n");
return -ENODEV;
}
}

nb = kcalloc(misc_count, sizeof(struct amd_northbridge), GFP_KERNEL);
if (!nb)
return -ENOMEM;

amd_northbridges.nb = nb;
amd_northbridges.num = i;
amd_northbridges.num = misc_count;

link = misc = root = NULL;
for (i = 0; i != amd_northbridges.num; i++) {
for (i = 0; i < amd_northbridges.num; i++) {
node_to_amd_nb(i)->root = root =
next_northbridge(root, root_ids);
node_to_amd_nb(i)->misc = misc =
next_northbridge(misc, misc_ids);
node_to_amd_nb(i)->link = link =
next_northbridge(link, link_ids);

/*
* If there are more PCI root devices than data fabric/
* system management network interfaces, then the (N)
* PCI roots per DF/SMN interface are functionally the
* same (for DF/SMN access) and N-1 are redundant. N-1
* PCI roots should be skipped per DF/SMN interface so
* the following DF/SMN interfaces get mapped to
* correct PCI roots.
*/
for (j = 1; j < roots_per_misc; j++)
root = next_northbridge(root, root_ids);
}

if (amd_gart_present())
Expand Down

0 comments on commit 556e4c6

Please sign in to comment.