Skip to content

Commit

Permalink
x86/PCI: Move and shrink AMD 64-bit window to avoid conflict
Browse files Browse the repository at this point in the history
Avoid problems with BIOS implementations which don't report all used
resources to the OS by only allocating a 256GB window directly below the
hardware limit (from the BKDG, sec 2.4.6).

Fixes a silent reboot loop reported by Aaro Koskinen <aaro.koskinen@iki.fi>
on an AMD-based MSI MS-7699/760GA-P43(FX) system.  This was apparently
caused by RAM or other unreported hardware that conflicted with the new
window.

Link: https://support.amd.com/TechDocs/49125_15h_Models_30h-3Fh_BKDG.pdf
Link: https://lkml.kernel.org/r/20180105220412.fzpwqe4zljdawr36@darkstar.musicnaut.iki.fi
Fixes: fa564ad ("x86/PCI: Enable a 64bit BAR on AMD Family 15h (Models 00-1f, 30-3f, 60-7f)")
Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Christian König <christian.koenig@amd.com>
[bhelgaas: changelog, comment, Fixes:]
Signed-off-by: Bjorn Helgaas <helgaas@kernel.org>
  • Loading branch information
=?UTF-8?q?Christian=20K=C3=B6nig?= authored and Bjorn Helgaas committed Jan 11, 2018
1 parent f32ab75 commit 03a5517
Showing 1 changed file with 12 additions and 10 deletions.
22 changes: 12 additions & 10 deletions arch/x86/pci/fixup.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,10 +662,11 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid);
*/
static void pci_amd_enable_64bit_bar(struct pci_dev *dev)
{
unsigned i;
u32 base, limit, high;
struct resource *res, *conflict;
struct pci_dev *other;
struct resource *res;
unsigned i;
int r;

if (!(pci_probe & PCI_BIG_ROOT_WINDOW))
return;
Expand Down Expand Up @@ -702,19 +703,20 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev)
if (!res)
return;

/*
* Allocate a 256GB window directly below the 0xfd00000000 hardware
* limit (see AMD Family 15h Models 30h-3Fh BKDG, sec 2.4.6).
*/
res->name = "PCI Bus 0000:00";
res->flags = IORESOURCE_PREFETCH | IORESOURCE_MEM |
IORESOURCE_MEM_64 | IORESOURCE_WINDOW;
res->start = 0x100000000ull;
res->start = 0xbd00000000ull;
res->end = 0xfd00000000ull - 1;

/* Just grab the free area behind system memory for this */
while ((conflict = request_resource_conflict(&iomem_resource, res))) {
if (conflict->end >= res->end) {
kfree(res);
return;
}
res->start = conflict->end + 1;
r = request_resource(&iomem_resource, res);
if (r) {
kfree(res);
return;
}

dev_info(&dev->dev, "adding root bus resource %pR (tainting kernel)\n",
Expand Down

0 comments on commit 03a5517

Please sign in to comment.