aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author=?UTF-8?q?Christian=20K=C3=B6nig?= <ckoenig.leichtzumerken@gmail.com>2018-01-11 08:23:29 -0500
committerBjorn Helgaas <helgaas@kernel.org>2018-01-11 12:22:39 -0500
commitf32ab7547161b9fa7ebfbc4f18ea1eb3fd49fe25 (patch)
treef806a04056ffadf4bdc92e4d70e1ff1488c713b0
parent1291a0d5049dbc06baaaf66a9ff3f53db493b19b (diff)
x86/PCI: Add "pci=big_root_window" option for AMD 64-bit windows
Only try to enable a 64-bit window on AMD CPUs when "pci=big_root_window" is specified. This taints the kernel because the new 64-bit window uses address space we don't know anything about, and it may contain unreported devices or memory that would conflict with the window. The pci_amd_enable_64bit_bar() quirk that enables the window is specific to AMD CPUs. The generic solution would be to have the firmware enable the window and describe it in the host bridge's _CRS method, or at least describe it in the _PRS method so the OS would have the option of enabling it. Signed-off-by: Christian König <christian.koenig@amd.com> [bhelgaas: changelog, extend doc, mention taint in dmesg] Signed-off-by: Bjorn Helgaas <helgaas@kernel.org>
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt6
-rw-r--r--arch/x86/include/asm/pci_x86.h1
-rw-r--r--arch/x86/pci/common.c5
-rw-r--r--arch/x86/pci/fixup.c7
4 files changed, 18 insertions, 1 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 6571fbfdb2a1..619638362416 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3094,6 +3094,12 @@
3094 pcie_scan_all Scan all possible PCIe devices. Otherwise we 3094 pcie_scan_all Scan all possible PCIe devices. Otherwise we
3095 only look for one device below a PCIe downstream 3095 only look for one device below a PCIe downstream
3096 port. 3096 port.
3097 big_root_window Try to add a big 64bit memory window to the PCIe
3098 root complex on AMD CPUs. Some GFX hardware
3099 can resize a BAR to allow access to all VRAM.
3100 Adding the window is slightly risky (it may
3101 conflict with unreported devices), so this
3102 taints the kernel.
3097 3103
3098 pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power 3104 pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
3099 Management. 3105 Management.
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 7a5d6695abd3..eb66fa9cd0fc 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -38,6 +38,7 @@ do { \
38#define PCI_NOASSIGN_ROMS 0x80000 38#define PCI_NOASSIGN_ROMS 0x80000
39#define PCI_ROOT_NO_CRS 0x100000 39#define PCI_ROOT_NO_CRS 0x100000
40#define PCI_NOASSIGN_BARS 0x200000 40#define PCI_NOASSIGN_BARS 0x200000
41#define PCI_BIG_ROOT_WINDOW 0x400000
41 42
42extern unsigned int pci_probe; 43extern unsigned int pci_probe;
43extern unsigned long pirq_table_addr; 44extern unsigned long pirq_table_addr;
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 7a5350d08cef..563049c483a1 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -594,6 +594,11 @@ char *__init pcibios_setup(char *str)
594 } else if (!strcmp(str, "nocrs")) { 594 } else if (!strcmp(str, "nocrs")) {
595 pci_probe |= PCI_ROOT_NO_CRS; 595 pci_probe |= PCI_ROOT_NO_CRS;
596 return NULL; 596 return NULL;
597#ifdef CONFIG_PHYS_ADDR_T_64BIT
598 } else if (!strcmp(str, "big_root_window")) {
599 pci_probe |= PCI_BIG_ROOT_WINDOW;
600 return NULL;
601#endif
597 } else if (!strcmp(str, "earlydump")) { 602 } else if (!strcmp(str, "earlydump")) {
598 pci_early_dump_regs = 1; 603 pci_early_dump_regs = 1;
599 return NULL; 604 return NULL;
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index e663d6bf1328..8bad19c7473d 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -667,6 +667,9 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev)
667 struct resource *res, *conflict; 667 struct resource *res, *conflict;
668 struct pci_dev *other; 668 struct pci_dev *other;
669 669
670 if (!(pci_probe & PCI_BIG_ROOT_WINDOW))
671 return;
672
670 /* Check that we are the only device of that type */ 673 /* Check that we are the only device of that type */
671 other = pci_get_device(dev->vendor, dev->device, NULL); 674 other = pci_get_device(dev->vendor, dev->device, NULL);
672 if (other != dev || 675 if (other != dev ||
@@ -714,7 +717,9 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev)
714 res->start = conflict->end + 1; 717 res->start = conflict->end + 1;
715 } 718 }
716 719
717 dev_info(&dev->dev, "adding root bus resource %pR\n", res); 720 dev_info(&dev->dev, "adding root bus resource %pR (tainting kernel)\n",
721 res);
722 add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
718 723
719 base = ((res->start >> 8) & AMD_141b_MMIO_BASE_MMIOBASE_MASK) | 724 base = ((res->start >> 8) & AMD_141b_MMIO_BASE_MMIOBASE_MASK) |
720 AMD_141b_MMIO_BASE_RE_MASK | AMD_141b_MMIO_BASE_WE_MASK; 725 AMD_141b_MMIO_BASE_RE_MASK | AMD_141b_MMIO_BASE_WE_MASK;