diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-14 20:02:39 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-14 20:02:39 -0500 |
commit | c4f988ee51ed896f5f709ba611a18485a2204ace (patch) | |
tree | e466c49fd83c33a865c68d4525b1c2f1865f939c | |
parent | 18d40eae7fb60ab1efa2a607b4b8a2d86036876a (diff) | |
parent | 0c31f1d7be1b5c4858b1d714dcefa25f41428cab (diff) |
Merge tag 'pci-v4.15-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI fixes from Bjorn Helgaas:
- add a pci_get_domain_bus_and_slot() stub for the CONFIG_PCI=n case to
avoid build breakage in the v4.16 merge window if a
pci_get_bus_and_slot() -> pci_get_domain_bus_and_slot() patch gets
merged before the PCI tree (Randy Dunlap)
- fix an AMD boot regression in the 64bit BAR support added in v4.15
(Christian König)
- fix an R-Car use-after-free that causes a crash if no PCIe card is
present (Geert Uytterhoeven)
* tag 'pci-v4.15-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
PCI: rcar: Fix use-after-free in probe error path
x86/PCI: Only enable a 64bit BAR on single-socket AMD Family 15h
x86/PCI: Fix infinite loop in search for 64bit BAR placement
PCI: Add pci_get_domain_bus_and_slot() stub
-rw-r--r-- | arch/x86/pci/fixup.c | 27 | ||||
-rw-r--r-- | drivers/pci/host/pcie-rcar.c | 8 | ||||
-rw-r--r-- | include/linux/pci.h | 3 |
3 files changed, 28 insertions, 10 deletions
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 1e996df687a3..e663d6bf1328 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -665,6 +665,16 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev) | |||
665 | unsigned i; | 665 | unsigned i; |
666 | u32 base, limit, high; | 666 | u32 base, limit, high; |
667 | struct resource *res, *conflict; | 667 | struct resource *res, *conflict; |
668 | struct pci_dev *other; | ||
669 | |||
670 | /* Check that we are the only device of that type */ | ||
671 | other = pci_get_device(dev->vendor, dev->device, NULL); | ||
672 | if (other != dev || | ||
673 | (other = pci_get_device(dev->vendor, dev->device, other))) { | ||
674 | /* This is a multi-socket system, don't touch it for now */ | ||
675 | pci_dev_put(other); | ||
676 | return; | ||
677 | } | ||
668 | 678 | ||
669 | for (i = 0; i < 8; i++) { | 679 | for (i = 0; i < 8; i++) { |
670 | pci_read_config_dword(dev, AMD_141b_MMIO_BASE(i), &base); | 680 | pci_read_config_dword(dev, AMD_141b_MMIO_BASE(i), &base); |
@@ -696,8 +706,13 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev) | |||
696 | res->end = 0xfd00000000ull - 1; | 706 | res->end = 0xfd00000000ull - 1; |
697 | 707 | ||
698 | /* Just grab the free area behind system memory for this */ | 708 | /* Just grab the free area behind system memory for this */ |
699 | while ((conflict = request_resource_conflict(&iomem_resource, res))) | 709 | while ((conflict = request_resource_conflict(&iomem_resource, res))) { |
710 | if (conflict->end >= res->end) { | ||
711 | kfree(res); | ||
712 | return; | ||
713 | } | ||
700 | res->start = conflict->end + 1; | 714 | res->start = conflict->end + 1; |
715 | } | ||
701 | 716 | ||
702 | dev_info(&dev->dev, "adding root bus resource %pR\n", res); | 717 | dev_info(&dev->dev, "adding root bus resource %pR\n", res); |
703 | 718 | ||
@@ -714,10 +729,10 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev) | |||
714 | 729 | ||
715 | pci_bus_add_resource(dev->bus, res, 0); | 730 | pci_bus_add_resource(dev->bus, res, 0); |
716 | } | 731 | } |
717 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1401, pci_amd_enable_64bit_bar); | 732 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1401, pci_amd_enable_64bit_bar); |
718 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x141b, pci_amd_enable_64bit_bar); | 733 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x141b, pci_amd_enable_64bit_bar); |
719 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1571, pci_amd_enable_64bit_bar); | 734 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1571, pci_amd_enable_64bit_bar); |
720 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x15b1, pci_amd_enable_64bit_bar); | 735 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15b1, pci_amd_enable_64bit_bar); |
721 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1601, pci_amd_enable_64bit_bar); | 736 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1601, pci_amd_enable_64bit_bar); |
722 | 737 | ||
723 | #endif | 738 | #endif |
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 12796eccb2be..52ab3cb0a0bf 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -1128,12 +1128,12 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
1128 | err = rcar_pcie_get_resources(pcie); | 1128 | err = rcar_pcie_get_resources(pcie); |
1129 | if (err < 0) { | 1129 | if (err < 0) { |
1130 | dev_err(dev, "failed to request resources: %d\n", err); | 1130 | dev_err(dev, "failed to request resources: %d\n", err); |
1131 | goto err_free_bridge; | 1131 | goto err_free_resource_list; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); | 1134 | err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); |
1135 | if (err) | 1135 | if (err) |
1136 | goto err_free_bridge; | 1136 | goto err_free_resource_list; |
1137 | 1137 | ||
1138 | pm_runtime_enable(dev); | 1138 | pm_runtime_enable(dev); |
1139 | err = pm_runtime_get_sync(dev); | 1139 | err = pm_runtime_get_sync(dev); |
@@ -1176,9 +1176,9 @@ err_pm_put: | |||
1176 | err_pm_disable: | 1176 | err_pm_disable: |
1177 | pm_runtime_disable(dev); | 1177 | pm_runtime_disable(dev); |
1178 | 1178 | ||
1179 | err_free_bridge: | 1179 | err_free_resource_list: |
1180 | pci_free_host_bridge(bridge); | ||
1181 | pci_free_resource_list(&pcie->resources); | 1180 | pci_free_resource_list(&pcie->resources); |
1181 | pci_free_host_bridge(bridge); | ||
1182 | 1182 | ||
1183 | return err; | 1183 | return err; |
1184 | } | 1184 | } |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 0403894147a3..c170c9250c8b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1674,6 +1674,9 @@ static inline struct pci_dev *pci_get_slot(struct pci_bus *bus, | |||
1674 | static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, | 1674 | static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, |
1675 | unsigned int devfn) | 1675 | unsigned int devfn) |
1676 | { return NULL; } | 1676 | { return NULL; } |
1677 | static inline struct pci_dev *pci_get_domain_bus_and_slot(int domain, | ||
1678 | unsigned int bus, unsigned int devfn) | ||
1679 | { return NULL; } | ||
1677 | 1680 | ||
1678 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } | 1681 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } |
1679 | static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; } | 1682 | static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; } |