diff options
author | =?UTF-8?q?Christian=20K=C3=B6nig?= <ckoenig.leichtzumerken@gmail.com> | 2018-01-11 08:23:29 -0500 |
---|---|---|
committer | Bjorn Helgaas <helgaas@kernel.org> | 2018-01-11 12:22:39 -0500 |
commit | f32ab7547161b9fa7ebfbc4f18ea1eb3fd49fe25 (patch) | |
tree | f806a04056ffadf4bdc92e4d70e1ff1488c713b0 | |
parent | 1291a0d5049dbc06baaaf66a9ff3f53db493b19b (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.txt | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/pci_x86.h | 1 | ||||
-rw-r--r-- | arch/x86/pci/common.c | 5 | ||||
-rw-r--r-- | arch/x86/pci/fixup.c | 7 |
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 | ||
42 | extern unsigned int pci_probe; | 43 | extern unsigned int pci_probe; |
43 | extern unsigned long pirq_table_addr; | 44 | extern 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; |