From c3f00182a83b590655cb68b43b9dcc6cdd05316a Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Thu, 6 Sep 2018 14:16:53 -0500 Subject: [PATCH 1/8] MAINTAINERS: Add entries for PPC64 RPA PCI hotplug drivers Add myself as maintainer of the IBM RPA hotplug modules in the drivers/pci/hotplug directory. These modules provide kernel interfaces for support of Dynamic Logical Partitioning (DLPAR) of Logical and Physical IO slots, and hotplug of physical PCI slots of a PHB on RPA-compliant ppc64 platforms (pseries). Signed-off-by: Tyrel Datwyler Signed-off-by: Bjorn Helgaas --- MAINTAINERS | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index a5b256b25905..3f3ed8fcb202 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7015,6 +7015,20 @@ F: drivers/crypto/vmx/aes* F: drivers/crypto/vmx/ghash* F: drivers/crypto/vmx/ppc-xlate.pl +IBM Power PCI Hotplug Driver for RPA-compliant PPC64 platform +M: Tyrel Datwyler +L: linux-pci@vger.kernel.org +L: linuxppc-dev@lists.ozlabs.org +S: Supported +F: drivers/pci/hotplug/rpaphp* + +IBM Power IO DLPAR Driver for RPA-compliant PPC64 platform +M: Tyrel Datwyler +L: linux-pci@vger.kernel.org +L: linuxppc-dev@lists.ozlabs.org +S: Supported +F: drivers/pci/hotplug/rpadlpar* + IBM ServeRAID RAID DRIVER S: Orphan F: drivers/scsi/ips.* From f30cf498b4277dcb20514f3f1daa89c2281f3395 Mon Sep 17 00:00:00 2001 From: Joao Pinto Date: Tue, 11 Sep 2018 13:06:30 +0100 Subject: [PATCH 2/8] MAINTAINERS: Add Gustavo Pimentel as DesignWare PCI maintainer Currently I am managing the Synopsys drivers & tools team (full-time) and so I am passing the pcie-designware maintenance to Gustavo. Signed-off-by: Joao Pinto Signed-off-by: Bjorn Helgaas CC: Gustavo Pimentel CC: Jingoo Han --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3f3ed8fcb202..7e10ba65bfe4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11167,7 +11167,7 @@ F: drivers/pci/controller/dwc/pci-exynos.c PCI DRIVER FOR SYNOPSYS DESIGNWARE M: Jingoo Han -M: Joao Pinto +M: Gustavo Pimentel L: linux-pci@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pci/designware-pcie.txt From 50ca031b51106b1b46162d4e9ecccb7edc95682f Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 5 Sep 2018 14:09:54 +0300 Subject: [PATCH 3/8] Revert "PCI: Add ACS quirk for Intel 300 series" This reverts f154a718e6cc ("PCI: Add ACS quirk for Intel 300 series"). It turns out that erratum "PCH PCIe* Controller Root Port (ACSCTLR) Appear As Read Only" has been fixed in 300 series chipsets, even though the datasheet [1] claims otherwise. To make ACS work properly on 300 series root ports, revert the faulty commit. [1] https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/300-series-c240-series-chipset-pch-spec-update.pdf Fixes: f154a718e6cc ("PCI: Add ACS quirk for Intel 300 series") Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org # v4.18+ --- drivers/pci/quirks.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ef7143a274e0..6bc27b7fd452 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4355,11 +4355,6 @@ static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags) * * 0x9d10-0x9d1b PCI Express Root port #{1-12} * - * The 300 series chipset suffers from the same bug so include those root - * ports here as well. - * - * 0xa32c-0xa343 PCI Express Root port #{0-24} - * * [1] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html * [2] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html * [3] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-spec-update.html @@ -4377,7 +4372,6 @@ static bool pci_quirk_intel_spt_pch_acs_match(struct pci_dev *dev) case 0xa110 ... 0xa11f: case 0xa167 ... 0xa16a: /* Sunrise Point */ case 0xa290 ... 0xa29f: case 0xa2e7 ... 0xa2ee: /* Union Point */ case 0x9d10 ... 0x9d1b: /* 7th & 8th Gen Mobile */ - case 0xa32c ... 0xa343: /* 300 series */ return true; } From 46feb6b495f7628a6dbf36c4e6d80faf378372d4 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 16 Aug 2018 14:06:46 -0500 Subject: [PATCH 4/8] switchtec: Fix Spectre v1 vulnerability p.port can is indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability. This issue was detected with the help of Smatch: drivers/pci/switch/switchtec.c:912 ioctl_port_to_pff() warn: potential spectre issue 'pcfg->dsp_pff_inst_id' [r] Fix this by sanitizing p.port before using it to index pcfg->dsp_pff_inst_id Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1]. [1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2 Signed-off-by: Gustavo A. R. Silva Signed-off-by: Bjorn Helgaas Acked-by: Logan Gunthorpe Cc: stable@vger.kernel.org --- drivers/pci/switch/switchtec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c index 9940cc70f38b..54a8b30dda38 100644 --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c @@ -14,6 +14,8 @@ #include #include +#include + MODULE_DESCRIPTION("Microsemi Switchtec(tm) PCIe Management Driver"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); @@ -909,6 +911,8 @@ static int ioctl_port_to_pff(struct switchtec_dev *stdev, default: if (p.port > ARRAY_SIZE(pcfg->dsp_pff_inst_id)) return -EINVAL; + p.port = array_index_nospec(p.port, + ARRAY_SIZE(pcfg->dsp_pff_inst_id) + 1); p.pff = ioread32(&pcfg->dsp_pff_inst_id[p.port - 1]); break; } From 34fb6bf9b13aef4ca14224f2175ecd189e98160b Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 5 Sep 2018 14:35:41 -0600 Subject: [PATCH 5/8] PCI: pciehp: Fix hot-add vs powerfault detection order If both hot-add and power fault were observed in a single interrupt, we handled the hot-add first, then the power fault, in this path: pciehp_ist if (events & (PDC | DLLSC)) pciehp_handle_presence_or_link_change case OFF_STATE: pciehp_enable_slot __pciehp_enable_slot board_added pciehp_power_on_slot ctrl->power_fault_detected = 0 pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_ON, PCI_EXP_SLTCTL_PCC) pciehp_green_led_on(p_slot) # power LED on pciehp_set_attention_status(p_slot, 0) # attention LED off if ((events & PFD) && !ctrl->power_fault_detected) ctrl->power_fault_detected = 1 pciehp_set_attention_status(1) # attention LED on pciehp_green_led_off(slot) # power LED off This left the attention indicator on (even though the hot-add succeeded) and the power indicator off (even though the slot power was on). Fix this by checking for power faults before checking for new devices. Prior to 0e94916e6091, this was successful because everything was chained through work queues and the order was: INT_PRESENCE_ON -> INT_POWER_FAULT -> ENABLE_REQ The ENABLE_REQ cleared the power fault at the end, but now everything is handled inline with the interrupt thread, such that the work ENABLE_REQ was doing happens before power fault handling now. Fixes: 0e94916e6091 ("PCI: pciehp: Handle events synchronously") Signed-off-by: Keith Busch [bhelgaas: changelog] Signed-off-by: Bjorn Helgaas Reviewed-by: Lukas Wunner --- drivers/pci/hotplug/pciehp_hpc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 7136e3430925..a938abdb41ce 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -496,7 +496,7 @@ int pciehp_power_on_slot(struct slot *slot) u16 slot_status; int retval; - /* Clear sticky power-fault bit from previous power failures */ + /* Clear power-fault bit from previous power failures */ pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); if (slot_status & PCI_EXP_SLTSTA_PFD) pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, @@ -646,6 +646,14 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) pciehp_handle_button_press(slot); } + /* Check Power Fault Detected */ + if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) { + ctrl->power_fault_detected = 1; + ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(slot)); + pciehp_set_attention_status(slot, 1); + pciehp_green_led_off(slot); + } + /* * Disable requests have higher priority than Presence Detect Changed * or Data Link Layer State Changed events. @@ -657,14 +665,6 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) pciehp_handle_presence_or_link_change(slot, events); up_read(&ctrl->reset_lock); - /* Check Power Fault Detected */ - if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) { - ctrl->power_fault_detected = 1; - ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(slot)); - pciehp_set_attention_status(slot, 1); - pciehp_green_led_off(slot); - } - pci_config_pm_runtime_put(pdev); wake_up(&ctrl->requester); return IRQ_HANDLED; From d8a5281035895cdb5ff77756eff72966ec76edd0 Mon Sep 17 00:00:00 2001 From: Dennis Dalessandro Date: Wed, 5 Sep 2018 16:08:03 +0000 Subject: [PATCH 6/8] PCI: Fix faulty logic in pci_reset_bus() The pci_reset_bus() function calls pci_probe_reset_slot() to determine whether to call the slot or bus reset. The check has faulty logic in that it does not account for pci_probe_reset_slot() being able to return an errno. Fix by only calling the slot reset when the function returns 0. Fixes: 811c5cb37df4 ("PCI: Unify try slot and bus reset API") Signed-off-by: Dennis Dalessandro Signed-off-by: Bjorn Helgaas Reviewed-by: Michael J. Ruhl Cc: Sinan Kaya --- drivers/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 29ff9619b5fa..30b260332a10 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5200,7 +5200,7 @@ static int __pci_reset_bus(struct pci_bus *bus) */ int pci_reset_bus(struct pci_dev *pdev) { - return pci_probe_reset_slot(pdev->slot) ? + return (!pci_probe_reset_slot(pdev->slot)) ? __pci_reset_slot(pdev->slot) : __pci_reset_bus(pdev->bus); } EXPORT_SYMBOL_GPL(pci_reset_bus); From bfc456060d0cbcf6902a436d358b60cb1534668c Mon Sep 17 00:00:00 2001 From: Dennis Dalessandro Date: Fri, 31 Aug 2018 10:34:14 -0700 Subject: [PATCH 7/8] IB/hfi1,PCI: Allow bus reset while probing Calling into the new API to reset the secondary bus results in a deadlock. This occurs because the device/bus is already locked at probe time. Reverting back to the old behavior while the API is improved. Link: https://bugzilla.kernel.org/show_bug.cgi?id=200985 Fixes: c6a44ba950d1 ("PCI: Rename pci_try_reset_bus() to pci_reset_bus()") Fixes: 409888e0966e ("IB/hfi1: Use pci_try_reset_bus() for initiating PCI Secondary Bus Reset") Signed-off-by: Dennis Dalessandro Signed-off-by: Bjorn Helgaas Reviewed-by: Michael J. Ruhl Cc: Sinan Kaya --- drivers/infiniband/hw/hfi1/pcie.c | 11 ++++------- drivers/pci/pci.c | 1 + include/linux/pci.h | 3 +++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c index eec83757d55f..6c967dde58e7 100644 --- a/drivers/infiniband/hw/hfi1/pcie.c +++ b/drivers/infiniband/hw/hfi1/pcie.c @@ -893,14 +893,11 @@ static int trigger_sbr(struct hfi1_devdata *dd) } /* - * A secondary bus reset (SBR) issues a hot reset to our device. - * The following routine does a 1s wait after the reset is dropped - * per PCI Trhfa (recovery time). PCIe 3.0 section 6.6.1 - - * Conventional Reset, paragraph 3, line 35 also says that a 1s - * delay after a reset is required. Per spec requirements, - * the link is either working or not after that point. + * This is an end around to do an SBR during probe time. A new API needs + * to be implemented to have cleaner interface but this fixes the + * current brokenness */ - return pci_reset_bus(dev); + return pci_bridge_secondary_bus_reset(dev->bus->self); } /* diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 30b260332a10..1835f3a7aa8d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4547,6 +4547,7 @@ int pci_bridge_secondary_bus_reset(struct pci_dev *dev) return pci_dev_wait(dev, "bus reset", PCIE_RESET_READY_POLL_MS); } +EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset); static int pci_parent_bus_reset(struct pci_dev *dev, int probe) { diff --git a/include/linux/pci.h b/include/linux/pci.h index e72ca8dd6241..6925828f9f25 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1235,6 +1235,9 @@ void pci_bus_remove_resources(struct pci_bus *bus); int devm_request_pci_bus_resources(struct device *dev, struct list_head *resources); +/* Temporary until new and working PCI SBR API in place */ +int pci_bridge_secondary_bus_reset(struct pci_dev *dev); + #define pci_bus_for_each_resource(bus, res, i) \ for (i = 0; \ (res = pci_bus_resource_n(bus, i)) || i < PCI_BRIDGE_RESOURCE_NUM; \ From 9d27e39d309c93025ae6aa97236af15bef2a5f1f Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Mon, 10 Sep 2018 15:27:42 -0400 Subject: [PATCH 8/8] PCI: Fix enabling of PASID on RC integrated endpoints Set the eetlp_prefix_path on PCIE_EXP_TYPE_RC_END devices to allow PASID to be enabled on them. This fixes IOMMUv2 initialization on AMD Carrizo APUs. Link: https://bugzilla.kernel.org/show_bug.cgi?id=201079 Fixes: 7ce3f912ae ("PCI: Enable PASID only if entire path supports End-End TLP prefixes") Signed-off-by: Felix Kuehling Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ec784009a36b..201f9e5ff55c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2074,6 +2074,7 @@ static void pci_configure_eetlp_prefix(struct pci_dev *dev) { #ifdef CONFIG_PCI_PASID struct pci_dev *bridge; + int pcie_type; u32 cap; if (!pci_is_pcie(dev)) @@ -2083,7 +2084,9 @@ static void pci_configure_eetlp_prefix(struct pci_dev *dev) if (!(cap & PCI_EXP_DEVCAP2_EE_PREFIX)) return; - if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) + pcie_type = pci_pcie_type(dev); + if (pcie_type == PCI_EXP_TYPE_ROOT_PORT || + pcie_type == PCI_EXP_TYPE_RC_END) dev->eetlp_prefix_path = 1; else { bridge = pci_upstream_bridge(dev);