Merge branch 'pci/virtualization'
authorBjorn Helgaas <bhelgaas@google.com>
Wed, 5 Aug 2020 23:24:17 +0000 (18:24 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 5 Aug 2020 23:24:17 +0000 (18:24 -0500)
- Remove redundant variable init in xen (Colin Ian King)

- Add pci_pri_supported() to check device or associated PF for PRI support
  (Ashok Raj)

- Mark AMD Navi10 GPU rev 0x00 ATS as broken (Kai-Heng Feng)

- Release IVRS table in AMD ACS quirk (Hanjun Guo)

* pci/virtualization:
  PCI: Release IVRS table in AMD ACS quirk
  PCI: Mark AMD Navi10 GPU rev 0x00 ATS as broken
  PCI/ATS: Add pci_pri_supported() to check device or associated PF
  xen: Remove redundant initialization of irq

54 files changed:
Documentation/PCI/pci-error-recovery.rst
Documentation/PCI/pci.rst
Documentation/devicetree/bindings/pci/pci.txt
arch/powerpc/kernel/eeh_driver.c
arch/x86/pci/fixup.c
drivers/block/rsxx/core.c
drivers/dma/ioat/init.c
drivers/gpu/drm/qxl/qxl_dev.h
drivers/iommu/intel/iommu.c
drivers/media/pci/ngene/ngene-cards.c
drivers/misc/genwqe/card_base.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ixgb/ixgb_main.c
drivers/net/ethernet/rocker/rocker_hw.h
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/falcon/efx.c
drivers/pci/access.c
drivers/pci/bus.c
drivers/pci/controller/dwc/pci-dra7xx.c
drivers/pci/controller/dwc/pci-exynos.c
drivers/pci/controller/dwc/pci-imx6.c
drivers/pci/controller/dwc/pci-keystone.c
drivers/pci/controller/dwc/pcie-designware-host.c
drivers/pci/controller/dwc/pcie-designware.c
drivers/pci/controller/dwc/pcie-designware.h
drivers/pci/controller/dwc/pcie-kirin.c
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/irq.c
drivers/pci/msi.c
drivers/pci/of.c
drivers/pci/p2pdma.c
drivers/pci/pci-acpi.c
drivers/pci/pci-label.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/Kconfig
drivers/pci/pcie/aer.c
drivers/pci/pcie/aer_inject.c
drivers/pci/pcie/aspm.c
drivers/pci/pcie/err.c
drivers/pci/pcie/portdrv_pci.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/setup-bus.c
drivers/pci/setup-res.c
drivers/pci/slot.c
drivers/scsi/aacraid/linit.c
drivers/scsi/smartpqi/smartpqi_init.c
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/staging/qlge/qlge_main.c
include/linux/pci.h
include/linux/pci_ids.h
samples/vfio-mdev/mdpy-defs.h

index 13beee2..ccd7134 100644 (file)
@@ -79,7 +79,7 @@ This structure has the form::
 
        struct pci_error_handlers
        {
-               int (*error_detected)(struct pci_dev *dev, enum pci_channel_state);
+               int (*error_detected)(struct pci_dev *dev, pci_channel_state_t);
                int (*mmio_enabled)(struct pci_dev *dev);
                int (*slot_reset)(struct pci_dev *dev);
                void (*resume)(struct pci_dev *dev);
@@ -87,11 +87,11 @@ This structure has the form::
 
 The possible channel states are::
 
-       enum pci_channel_state {
+       typedef enum {
                pci_channel_io_normal,  /* I/O channel is in normal state */
                pci_channel_io_frozen,  /* I/O to channel is blocked */
                pci_channel_io_perm_failure, /* PCI card is dead */
-       };
+       } pci_channel_state_t;
 
 Possible return values are::
 
@@ -348,7 +348,7 @@ STEP 6: Permanent Failure
 -------------------------
 A "permanent failure" has occurred, and the platform cannot recover
 the device.  The platform will call error_detected() with a
-pci_channel_state value of pci_channel_io_perm_failure.
+pci_channel_state_t value of pci_channel_io_perm_failure.
 
 The device driver should, at this point, assume the worst. It should
 cancel all pending I/O, refuse all new I/O, returning -EIO to
index 8c016d8..281d8a2 100644 (file)
@@ -17,7 +17,7 @@ PCI device drivers.
 A more complete resource is the third edition of "Linux Device Drivers"
 by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman.
 LDD3 is available for free (under Creative Commons License) from:
-http://lwn.net/Kernel/LDD3/.
+https://lwn.net/Kernel/LDD3/.
 
 However, keep in mind that all documents are subject to "bit rot".
 Refer to the source code if things are not working as described here.
@@ -214,7 +214,7 @@ the PCI device by calling pci_enable_device(). This will:
    problem and unlikely to get fixed soon.
 
    This has been discussed before but not changed as of 2.6.19:
-   http://lkml.org/lkml/2006/3/2/194
+   https://lore.kernel.org/r/20060302180025.GC28895@flint.arm.linux.org.uk/
 
 
 pci_set_master() will enable DMA by setting the bus master bit
@@ -514,9 +514,8 @@ your driver if they're helpful, or just use plain hex constants.
 The device IDs are arbitrary hex numbers (vendor controlled) and normally used
 only in a single location, the pci_device_id table.
 
-Please DO submit new vendor/device IDs to http://pci-ids.ucw.cz/.
-There are mirrors of the pci.ids file at http://pciids.sourceforge.net/
-and https://github.com/pciutils/pciids.
+Please DO submit new vendor/device IDs to https://pci-ids.ucw.cz/.
+There's a mirror of the pci.ids file at https://github.com/pciutils/pciids.
 
 
 Obsolete functions
index 29bcbd8..6a8f287 100644 (file)
@@ -1,12 +1,12 @@
 PCI bus bridges have standardized Device Tree bindings:
 
 PCI Bus Binding to: IEEE Std 1275-1994
-http://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf
+https://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf
 
 And for the interrupt mapping part:
 
 Open Firmware Recommended Practice: Interrupt Mapping
-http://www.devicetree.org/open-firmware/practice/imap/imap0_9d.pdf
+https://www.devicetree.org/open-firmware/practice/imap/imap0_9d.pdf
 
 Additionally to the properties specified in the above standards a host bridge
 driver implementation may support the following properties:
index 7b048ce..ab8806d 100644 (file)
@@ -214,7 +214,7 @@ static void eeh_dev_save_state(struct eeh_dev *edev, void *userdata)
        pci_save_state(pdev);
 }
 
-static void eeh_set_channel_state(struct eeh_pe *root, enum pci_channel_state s)
+static void eeh_set_channel_state(struct eeh_pe *root, pci_channel_state_t s)
 {
        struct eeh_pe *pe;
        struct eeh_dev *edev, *tmp;
index 0c67a5a..b8c9a5b 100644 (file)
@@ -557,12 +557,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_z
  * Device [8086:2fc0]
  * Erratum HSE43
  * CONFIG_TDP_NOMINAL CSR Implemented at Incorrect Offset
- * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v3-spec-update.html
+ * https://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v3-spec-update.html
  *
  * Devices [8086:6f60,6fa0,6fc0]
  * Erratum BDF2
  * PCI BARs in the Home Agent Will Return Non-Zero Values During Enumeration
- * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-spec-update.html
+ * https://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-spec-update.html
  */
 static void pci_invalid_bar(struct pci_dev *dev)
 {
index 10f6368..34e937d 100644 (file)
@@ -625,7 +625,7 @@ static int rsxx_eeh_fifo_flush_poll(struct rsxx_cardinfo *card)
 }
 
 static pci_ers_result_t rsxx_error_detected(struct pci_dev *dev,
-                                           enum pci_channel_state error)
+                                           pci_channel_state_t error)
 {
        int st;
 
index 58d1356..20a4f36 100644 (file)
@@ -1195,13 +1195,13 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca)
        /* disable relaxed ordering */
        err = pcie_capability_read_word(pdev, IOAT_DEVCTRL_OFFSET, &val16);
        if (err)
-               return err;
+               return pcibios_err_to_errno(err);
 
        /* clear relaxed ordering enable */
        val16 &= ~IOAT_DEVCTRL_ROE;
        err = pcie_capability_write_word(pdev, IOAT_DEVCTRL_OFFSET, val16);
        if (err)
-               return err;
+               return pcibios_err_to_errno(err);
 
        if (ioat_dma->cap & IOAT_CAP_DPS)
                writeb(ioat_pending_level + 1,
@@ -1267,7 +1267,7 @@ static void ioat_resume(struct ioatdma_device *ioat_dma)
 #define DRV_NAME "ioatdma"
 
 static pci_ers_result_t ioat_pcie_error_detected(struct pci_dev *pdev,
-                                                enum pci_channel_state error)
+                                                pci_channel_state_t error)
 {
        dev_dbg(&pdev->dev, "%s: PCIe AER error %d\n", DRV_NAME, error);
 
index a0ee416..a7bc31f 100644 (file)
@@ -131,8 +131,6 @@ enum SpiceCursorType {
 
 #pragma pack(push, 1)
 
-#define REDHAT_PCI_VENDOR_ID 0x1b36
-
 /* 0x100-0x11f reserved for spice, 0x1ff used for unstable work */
 #define QXL_DEVICE_ID_STABLE 0x0100
 
index 5552e7d..1311048 100644 (file)
@@ -4730,12 +4730,12 @@ const struct attribute_group *intel_iommu_groups[] = {
        NULL,
 };
 
-static inline bool has_untrusted_dev(void)
+static inline bool has_external_pci(void)
 {
        struct pci_dev *pdev = NULL;
 
        for_each_pci_dev(pdev)
-               if (pdev->untrusted)
+               if (pdev->external_facing)
                        return true;
 
        return false;
@@ -4743,7 +4743,7 @@ static inline bool has_untrusted_dev(void)
 
 static int __init platform_optin_force_iommu(void)
 {
-       if (!dmar_platform_optin() || no_platform_optin || !has_untrusted_dev())
+       if (!dmar_platform_optin() || no_platform_optin || !has_external_pci())
                return 0;
 
        if (no_iommu || dmar_disabled)
index 6185806..8bfb3d8 100644 (file)
@@ -1186,7 +1186,7 @@ MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
 /****************************************************************************/
 
 static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
-                                            enum pci_channel_state state)
+                                            pci_channel_state_t state)
 {
        dev_err(&dev->dev, "PCI error\n");
        if (state == pci_channel_io_perm_failure)
index 1dc6c7c..97b8ecc 100644 (file)
@@ -1240,7 +1240,7 @@ static void genwqe_remove(struct pci_dev *pci_dev)
  * error is detected.
  */
 static pci_ers_result_t genwqe_err_error_detected(struct pci_dev *pci_dev,
-                                                enum pci_channel_state state)
+                                                pci_channel_state_t state)
 {
        struct genwqe_dev *cd;
 
index 5d807c8..f0de2d1 100644 (file)
@@ -15465,7 +15465,7 @@ unmap:
  * remediation.
  **/
 static pci_ers_result_t i40e_pci_error_detected(struct pci_dev *pdev,
-                                               enum pci_channel_state error)
+                                               pci_channel_state_t error)
 {
        struct i40e_pf *pf = pci_get_drvdata(pdev);
 
index 082825e..4dd9226 100644 (file)
@@ -3586,7 +3586,7 @@ static void ice_remove(struct pci_dev *pdev)
  * is in progress.  Allows the driver to gracefully prepare/handle PCI errors.
  */
 static pci_ers_result_t
-ice_pci_err_detected(struct pci_dev *pdev, enum pci_channel_state err)
+ice_pci_err_detected(struct pci_dev *pdev, pci_channel_state_t err)
 {
        struct ice_pf *pf = pci_get_drvdata(pdev);
 
index b64e91e..00db4b5 100644 (file)
@@ -82,7 +82,7 @@ static int ixgb_vlan_rx_kill_vid(struct net_device *netdev,
 static void ixgb_restore_vlan(struct ixgb_adapter *adapter);
 
 static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
-                             enum pci_channel_state state);
+                             pci_channel_state_t state);
 static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev);
 static void ixgb_io_resume (struct pci_dev *pdev);
 
@@ -2194,7 +2194,7 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter)
  * a PCI bus error is detected.
  */
 static pci_ers_result_t ixgb_io_error_detected(struct pci_dev *pdev,
-                                               enum pci_channel_state state)
+                                               pci_channel_state_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct ixgb_adapter *adapter = netdev_priv(netdev);
index 59f1f8b..62fd84c 100644 (file)
@@ -25,7 +25,6 @@ enum {
 
 #define ROCKER_FP_PORTS_MAX 62
 
-#define PCI_VENDOR_ID_REDHAT           0x1b36
 #define PCI_DEVICE_ID_REDHAT_ROCKER    0x0006
 
 #define ROCKER_PCI_BAR0_SIZE           0x2000
index 256807c..ed627af 100644 (file)
@@ -1519,7 +1519,7 @@ static const struct dev_pm_ops efx_pm_ops = {
  * Stop the software path and request a slot reset.
  */
 static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev,
-                                             enum pci_channel_state state)
+                                             pci_channel_state_t state)
 {
        pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
        struct efx_nic *efx = pci_get_drvdata(pdev);
index 42bcd34..f897999 100644 (file)
@@ -3118,7 +3118,7 @@ static const struct dev_pm_ops ef4_pm_ops = {
  * Stop the software path and request a slot reset.
  */
 static pci_ers_result_t ef4_io_error_detected(struct pci_dev *pdev,
-                                             enum pci_channel_state state)
+                                             pci_channel_state_t state)
 {
        pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
        struct ef4_nic *efx = pci_get_drvdata(pdev);
index 79c4a2e..4693569 100644 (file)
@@ -204,17 +204,13 @@ EXPORT_SYMBOL(pci_bus_set_ops);
 static DECLARE_WAIT_QUEUE_HEAD(pci_cfg_wait);
 
 static noinline void pci_wait_cfg(struct pci_dev *dev)
+       __must_hold(&pci_lock)
 {
-       DECLARE_WAITQUEUE(wait, current);
-
-       __add_wait_queue(&pci_cfg_wait, &wait);
        do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
                raw_spin_unlock_irq(&pci_lock);
-               schedule();
+               wait_event(pci_cfg_wait, !dev->block_cfg_access);
                raw_spin_lock_irq(&pci_lock);
        } while (dev->block_cfg_access);
-       __remove_wait_queue(&pci_cfg_wait, &wait);
 }
 
 /* Returns 0 on success, negative values indicate error. */
@@ -409,7 +405,7 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
 
        *val = 0;
        if (pos & 1)
-               return -EINVAL;
+               return PCIBIOS_BAD_REGISTER_NUMBER;
 
        if (pcie_capability_reg_implemented(dev, pos)) {
                ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val);
@@ -444,7 +440,7 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)
 
        *val = 0;
        if (pos & 3)
-               return -EINVAL;
+               return PCIBIOS_BAD_REGISTER_NUMBER;
 
        if (pcie_capability_reg_implemented(dev, pos)) {
                ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val);
@@ -469,7 +465,7 @@ EXPORT_SYMBOL(pcie_capability_read_dword);
 int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val)
 {
        if (pos & 1)
-               return -EINVAL;
+               return PCIBIOS_BAD_REGISTER_NUMBER;
 
        if (!pcie_capability_reg_implemented(dev, pos))
                return 0;
@@ -481,7 +477,7 @@ EXPORT_SYMBOL(pcie_capability_write_word);
 int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val)
 {
        if (pos & 3)
-               return -EINVAL;
+               return PCIBIOS_BAD_REGISTER_NUMBER;
 
        if (!pcie_capability_reg_implemented(dev, pos))
                return 0;
index 8e40b3e..3cef835 100644 (file)
@@ -322,12 +322,8 @@ void pci_bus_add_device(struct pci_dev *dev)
 
        dev->match_driver = true;
        retval = device_attach(&dev->dev);
-       if (retval < 0 && retval != -EPROBE_DEFER) {
+       if (retval < 0 && retval != -EPROBE_DEFER)
                pci_warn(dev, "device attach failed (%d)\n", retval);
-               pci_proc_detach_device(dev);
-               pci_remove_sysfs_dev_files(dev);
-               return;
-       }
 
        pci_dev_assign_added(dev, true);
 }
index 6184ebc..1b2e6e6 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs
  *
- * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com
+ * Copyright (C) 2013-2014 Texas Instruments Incorporated - https://www.ti.com
  *
  * Authors: Kishon Vijay Abraham I <kishon@ti.com>
  */
index c5043d9..a075eba 100644 (file)
@@ -3,7 +3,7 @@
  * PCIe host controller driver for Samsung Exynos SoCs
  *
  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
+ *             https://www.samsung.com
  *
  * Author: Jingoo Han <jg1.han@samsung.com>
  */
index 8f08ae5..4e5c379 100644 (file)
@@ -3,7 +3,7 @@
  * PCIe host controller driver for Freescale i.MX6 SoCs
  *
  * Copyright (C) 2013 Kosagi
- *             http://www.kosagi.com
+ *             https://www.kosagi.com
  *
  * Author: Sean Cross <xobs@kosagi.com>
  */
index 790679f..5191cad 100644 (file)
@@ -3,7 +3,7 @@
  * PCIe host controller driver for Texas Instruments Keystone SoCs
  *
  * Copyright (C) 2013-2014 Texas Instruments., Ltd.
- *             http://www.ti.com
+ *             https://www.ti.com
  *
  * Author: Murali Karicheri <m-karicheri2@ti.com>
  * Implementation based on pci-exynos.c and pcie-designware.c
index 0a4a5aa..2cb286a 100644 (file)
@@ -3,7 +3,7 @@
  * Synopsys DesignWare PCIe host controller driver
  *
  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
+ *             https://www.samsung.com
  *
  * Author: Jingoo Han <jg1.han@samsung.com>
  */
index c92496e..b723e0c 100644 (file)
@@ -3,7 +3,7 @@
  * Synopsys DesignWare PCIe host controller driver
  *
  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
+ *             https://www.samsung.com
  *
  * Author: Jingoo Han <jg1.han@samsung.com>
  */
index 656e00f..90915dc 100644 (file)
@@ -3,7 +3,7 @@
  * Synopsys DesignWare PCIe host controller driver
  *
  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
+ *             https://www.samsung.com
  *
  * Author: Jingoo Han <jg1.han@samsung.com>
  */
index c19617a..7b86c16 100644 (file)
@@ -3,7 +3,7 @@
  * PCIe host controller driver for Kirin Phone SoCs
  *
  * Copyright (C) 2017 HiSilicon Electronics Co., Ltd.
- *             http://www.huawei.com
+ *             https://www.huawei.com
  *
  * Author: Xiaowei Song <songxiaowei@huawei.com>
  */
index c5eb509..f979b70 100644 (file)
@@ -352,7 +352,7 @@ static int dlpar_remove_vio_slot(char *drc_name, struct device_node *dn)
  * -ENODEV             Not a valid drc_name
  * -EIO                        Internal PCI Error
  */
-int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
+static int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
 {
        struct pci_bus *bus;
        struct slot *slot;
@@ -458,7 +458,7 @@ static inline int is_dlpar_capable(void)
        return (int) (rc != RTAS_UNKNOWN_SERVICE);
 }
 
-int __init rpadlpar_io_init(void)
+static int __init rpadlpar_io_init(void)
 {
 
        if (!is_dlpar_capable()) {
@@ -470,7 +470,7 @@ int __init rpadlpar_io_init(void)
        return dlpar_sysfs_init();
 }
 
-void rpadlpar_io_exit(void)
+static void __exit rpadlpar_io_exit(void)
 {
        dlpar_sysfs_exit();
 }
index a1de501..12ecd0a 100644 (file)
@@ -6,61 +6,11 @@
  * Copyright (C) 2017 Christoph Hellwig.
  */
 
-#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/pci.h>
 
-static void pci_note_irq_problem(struct pci_dev *pdev, const char *reason)
-{
-       struct pci_dev *parent = to_pci_dev(pdev->dev.parent);
-
-       pci_err(pdev, "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
-               dev_name(&parent->dev), parent->vendor, parent->device);
-       pci_err(pdev, "%s\n", reason);
-       pci_err(pdev, "Please report to linux-kernel@vger.kernel.org\n");
-       WARN_ON(1);
-}
-
-/**
- * pci_lost_interrupt - reports a lost PCI interrupt
- * @pdev:      device whose interrupt is lost
- *
- * The primary function of this routine is to report a lost interrupt
- * in a standard way which users can recognise (instead of blaming the
- * driver).
- *
- * Returns:
- * a suggestion for fixing it (although the driver is not required to
- * act on this).
- */
-enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *pdev)
-{
-       if (pdev->msi_enabled || pdev->msix_enabled) {
-               enum pci_lost_interrupt_reason ret;
-
-               if (pdev->msix_enabled) {
-                       pci_note_irq_problem(pdev, "MSIX routing failure");
-                       ret = PCI_LOST_IRQ_DISABLE_MSIX;
-               } else {
-                       pci_note_irq_problem(pdev, "MSI routing failure");
-                       ret = PCI_LOST_IRQ_DISABLE_MSI;
-               }
-               return ret;
-       }
-#ifdef CONFIG_ACPI
-       if (!(acpi_disabled || acpi_noirq)) {
-               pci_note_irq_problem(pdev, "Potential ACPI misrouting please reboot with acpi=noirq");
-               /* currently no way to fix acpi on the fly */
-               return PCI_LOST_IRQ_DISABLE_ACPI;
-       }
-#endif
-       pci_note_irq_problem(pdev, "unknown cause (not MSI or ACPI)");
-       return PCI_LOST_IRQ_NO_INFORMATION;
-}
-EXPORT_SYMBOL(pci_lost_interrupt);
-
 /**
  * pci_request_irq - allocate an interrupt line for a PCI device
  * @dev:       PCI device to operate on
index 6b43a54..cade9be 100644 (file)
@@ -1191,8 +1191,7 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,
                                   struct irq_affinity *affd)
 {
        struct irq_affinity msi_default_affd = {0};
-       int msix_vecs = -ENOSPC;
-       int msi_vecs = -ENOSPC;
+       int nvecs = -ENOSPC;
 
        if (flags & PCI_IRQ_AFFINITY) {
                if (!affd)
@@ -1203,17 +1202,16 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,
        }
 
        if (flags & PCI_IRQ_MSIX) {
-               msix_vecs = __pci_enable_msix_range(dev, NULL, min_vecs,
-                                                   max_vecs, affd, flags);
-               if (msix_vecs > 0)
-                       return msix_vecs;
+               nvecs = __pci_enable_msix_range(dev, NULL, min_vecs, max_vecs,
+                                               affd, flags);
+               if (nvecs > 0)
+                       return nvecs;
        }
 
        if (flags & PCI_IRQ_MSI) {
-               msi_vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs,
-                                                 affd);
-               if (msi_vecs > 0)
-                       return msi_vecs;
+               nvecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, affd);
+               if (nvecs > 0)
+                       return nvecs;
        }
 
        /* use legacy IRQ if allowed */
@@ -1231,9 +1229,7 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,
                }
        }
 
-       if (msix_vecs == -ENOSPC)
-               return -ENOSPC;
-       return msi_vecs;
+       return nvecs;
 }
 EXPORT_SYMBOL(pci_alloc_irq_vectors_affinity);
 
index 27839cd..22727fc 100644 (file)
@@ -42,7 +42,7 @@ void pci_set_bus_of_node(struct pci_bus *bus)
        } else {
                node = of_node_get(bus->self->dev.of_node);
                if (node && of_property_read_bool(node, "external-facing"))
-                       bus->self->untrusted = true;
+                       bus->self->external_facing = true;
        }
 
        bus->dev.of_node = node;
index e8e444e..64ebed1 100644 (file)
@@ -253,7 +253,7 @@ static int pci_bridge_has_acs_redir(struct pci_dev *pdev)
        int pos;
        u16 ctrl;
 
-       pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ACS);
+       pos = pdev->acs_cap;
        if (!pos)
                return 0;
 
@@ -273,6 +273,19 @@ static void seq_buf_print_bus_devfn(struct seq_buf *buf, struct pci_dev *pdev)
        seq_buf_printf(buf, "%s;", pci_name(pdev));
 }
 
+static bool cpu_supports_p2pdma(void)
+{
+#ifdef CONFIG_X86
+       struct cpuinfo_x86 *c = &cpu_data(0);
+
+       /* Any AMD CPU whose family ID is Zen or newer supports p2pdma */
+       if (c->x86_vendor == X86_VENDOR_AMD && c->x86 >= 0x17)
+               return true;
+#endif
+
+       return false;
+}
+
 static const struct pci_p2pdma_whitelist_entry {
        unsigned short vendor;
        unsigned short device;
@@ -280,11 +293,6 @@ static const struct pci_p2pdma_whitelist_entry {
                REQ_SAME_HOST_BRIDGE    = 1 << 0,
        } flags;
 } pci_p2pdma_whitelist[] = {
-       /* AMD ZEN */
-       {PCI_VENDOR_ID_AMD,     0x1450, 0},
-       {PCI_VENDOR_ID_AMD,     0x15d0, 0},
-       {PCI_VENDOR_ID_AMD,     0x1630, 0},
-
        /* Intel Xeon E5/Core i7 */
        {PCI_VENDOR_ID_INTEL,   0x3c00, REQ_SAME_HOST_BRIDGE},
        {PCI_VENDOR_ID_INTEL,   0x3c01, REQ_SAME_HOST_BRIDGE},
@@ -473,7 +481,8 @@ upstream_bridge_distance(struct pci_dev *provider, struct pci_dev *client,
                                              acs_redirects, acs_list);
 
        if (map_type == PCI_P2PDMA_MAP_THRU_HOST_BRIDGE) {
-               if (!host_bridge_whitelist(provider, client))
+               if (!cpu_supports_p2pdma() &&
+                   !host_bridge_whitelist(provider, client))
                        map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
        }
 
index 7224b1e..54520d3 100644 (file)
@@ -1213,7 +1213,7 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev,
        ACPI_FREE(obj);
 }
 
-static void pci_acpi_set_untrusted(struct pci_dev *dev)
+static void pci_acpi_set_external_facing(struct pci_dev *dev)
 {
        u8 val;
 
@@ -1224,11 +1224,10 @@ static void pci_acpi_set_untrusted(struct pci_dev *dev)
 
        /*
         * These root ports expose PCIe (including DMA) outside of the
-        * system so make sure we treat them and everything behind as
-        * untrusted.
+        * system.  Everything downstream from them is external.
         */
        if (val)
-               dev->untrusted = 1;
+               dev->external_facing = 1;
 }
 
 static void pci_acpi_setup(struct device *dev)
@@ -1240,7 +1239,7 @@ static void pci_acpi_setup(struct device *dev)
                return;
 
        pci_acpi_optimize_delay(pci_dev, adev->handle);
-       pci_acpi_set_untrusted(pci_dev);
+       pci_acpi_set_external_facing(pci_dev);
        pci_acpi_add_edr_notifier(pci_dev);
 
        pci_acpi_add_pm_notifier(adev, pci_dev);
index 707dd98..781e45c 100644 (file)
@@ -18,7 +18,7 @@
  * the instance number and string from the type 41 record and exports
  * it to sysfs.
  *
- * Please see http://linux.dell.com/files/biosdevname/ for more
+ * Please see https://linux.dell.com/files/biosdevname/ for more
  * information.
  */
 
index ce09627..501035c 100644 (file)
@@ -777,6 +777,133 @@ int pci_wait_for_pending(struct pci_dev *dev, int pos, u16 mask)
        return 0;
 }
 
+static int pci_acs_enable;
+
+/**
+ * pci_request_acs - ask for ACS to be enabled if supported
+ */
+void pci_request_acs(void)
+{
+       pci_acs_enable = 1;
+}
+
+static const char *disable_acs_redir_param;
+
+/**
+ * pci_disable_acs_redir - disable ACS redirect capabilities
+ * @dev: the PCI device
+ *
+ * For only devices specified in the disable_acs_redir parameter.
+ */
+static void pci_disable_acs_redir(struct pci_dev *dev)
+{
+       int ret = 0;
+       const char *p;
+       int pos;
+       u16 ctrl;
+
+       if (!disable_acs_redir_param)
+               return;
+
+       p = disable_acs_redir_param;
+       while (*p) {
+               ret = pci_dev_str_match(dev, p, &p);
+               if (ret < 0) {
+                       pr_info_once("PCI: Can't parse disable_acs_redir parameter: %s\n",
+                                    disable_acs_redir_param);
+
+                       break;
+               } else if (ret == 1) {
+                       /* Found a match */
+                       break;
+               }
+
+               if (*p != ';' && *p != ',') {
+                       /* End of param or invalid format */
+                       break;
+               }
+               p++;
+       }
+
+       if (ret != 1)
+               return;
+
+       if (!pci_dev_specific_disable_acs_redir(dev))
+               return;
+
+       pos = dev->acs_cap;
+       if (!pos) {
+               pci_warn(dev, "cannot disable ACS redirect for this hardware as it does not have ACS capabilities\n");
+               return;
+       }
+
+       pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
+
+       /* P2P Request & Completion Redirect */
+       ctrl &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC);
+
+       pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
+
+       pci_info(dev, "disabled ACS redirect\n");
+}
+
+/**
+ * pci_std_enable_acs - enable ACS on devices using standard ACS capabilities
+ * @dev: the PCI device
+ */
+static void pci_std_enable_acs(struct pci_dev *dev)
+{
+       int pos;
+       u16 cap;
+       u16 ctrl;
+
+       pos = dev->acs_cap;
+       if (!pos)
+               return;
+
+       pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
+       pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
+
+       /* Source Validation */
+       ctrl |= (cap & PCI_ACS_SV);
+
+       /* P2P Request Redirect */
+       ctrl |= (cap & PCI_ACS_RR);
+
+       /* P2P Completion Redirect */
+       ctrl |= (cap & PCI_ACS_CR);
+
+       /* Upstream Forwarding */
+       ctrl |= (cap & PCI_ACS_UF);
+
+       pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
+}
+
+/**
+ * pci_enable_acs - enable ACS if hardware support it
+ * @dev: the PCI device
+ */
+static void pci_enable_acs(struct pci_dev *dev)
+{
+       if (!pci_acs_enable)
+               goto disable_acs_redir;
+
+       if (!pci_dev_specific_enable_acs(dev))
+               goto disable_acs_redir;
+
+       pci_std_enable_acs(dev);
+
+disable_acs_redir:
+       /*
+        * Note: pci_disable_acs_redir() must be called even if ACS was not
+        * enabled by the kernel because it may have been enabled by
+        * platform firmware.  So if we are told to disable it, we should
+        * always disable it after setting the kernel's default
+        * preferences.
+        */
+       pci_disable_acs_redir(dev);
+}
+
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
  * @dev: PCI device to have its BARs restored
@@ -2046,6 +2173,14 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
 }
 EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state);
 
+void pcie_clear_device_status(struct pci_dev *dev)
+{
+       u16 sta;
+
+       pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &sta);
+       pcie_capability_write_word(dev, PCI_EXP_DEVSTA, sta);
+}
+
 /**
  * pcie_clear_root_pme_status - Clear root port PME interrupt status.
  * @dev: PCIe root port or event collector.
@@ -3230,139 +3365,12 @@ void pci_configure_ari(struct pci_dev *dev)
        }
 }
 
-static int pci_acs_enable;
-
-/**
- * pci_request_acs - ask for ACS to be enabled if supported
- */
-void pci_request_acs(void)
-{
-       pci_acs_enable = 1;
-}
-
-static const char *disable_acs_redir_param;
-
-/**
- * pci_disable_acs_redir - disable ACS redirect capabilities
- * @dev: the PCI device
- *
- * For only devices specified in the disable_acs_redir parameter.
- */
-static void pci_disable_acs_redir(struct pci_dev *dev)
-{
-       int ret = 0;
-       const char *p;
-       int pos;
-       u16 ctrl;
-
-       if (!disable_acs_redir_param)
-               return;
-
-       p = disable_acs_redir_param;
-       while (*p) {
-               ret = pci_dev_str_match(dev, p, &p);
-               if (ret < 0) {
-                       pr_info_once("PCI: Can't parse disable_acs_redir parameter: %s\n",
-                                    disable_acs_redir_param);
-
-                       break;
-               } else if (ret == 1) {
-                       /* Found a match */
-                       break;
-               }
-
-               if (*p != ';' && *p != ',') {
-                       /* End of param or invalid format */
-                       break;
-               }
-               p++;
-       }
-
-       if (ret != 1)
-               return;
-
-       if (!pci_dev_specific_disable_acs_redir(dev))
-               return;
-
-       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
-       if (!pos) {
-               pci_warn(dev, "cannot disable ACS redirect for this hardware as it does not have ACS capabilities\n");
-               return;
-       }
-
-       pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
-
-       /* P2P Request & Completion Redirect */
-       ctrl &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC);
-
-       pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
-
-       pci_info(dev, "disabled ACS redirect\n");
-}
-
-/**
- * pci_std_enable_acs - enable ACS on devices using standard ACS capabilities
- * @dev: the PCI device
- */
-static void pci_std_enable_acs(struct pci_dev *dev)
-{
-       int pos;
-       u16 cap;
-       u16 ctrl;
-
-       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
-       if (!pos)
-               return;
-
-       pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
-       pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
-
-       /* Source Validation */
-       ctrl |= (cap & PCI_ACS_SV);
-
-       /* P2P Request Redirect */
-       ctrl |= (cap & PCI_ACS_RR);
-
-       /* P2P Completion Redirect */
-       ctrl |= (cap & PCI_ACS_CR);
-
-       /* Upstream Forwarding */
-       ctrl |= (cap & PCI_ACS_UF);
-
-       pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
-}
-
-/**
- * pci_enable_acs - enable ACS if hardware support it
- * @dev: the PCI device
- */
-void pci_enable_acs(struct pci_dev *dev)
-{
-       if (!pci_acs_enable)
-               goto disable_acs_redir;
-
-       if (!pci_dev_specific_enable_acs(dev))
-               goto disable_acs_redir;
-
-       pci_std_enable_acs(dev);
-
-disable_acs_redir:
-       /*
-        * Note: pci_disable_acs_redir() must be called even if ACS was not
-        * enabled by the kernel because it may have been enabled by
-        * platform firmware.  So if we are told to disable it, we should
-        * always disable it after setting the kernel's default
-        * preferences.
-        */
-       pci_disable_acs_redir(dev);
-}
-
 static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
 {
        int pos;
        u16 cap, ctrl;
 
-       pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ACS);
+       pos = pdev->acs_cap;
        if (!pos)
                return false;
 
@@ -3487,6 +3495,18 @@ bool pci_acs_path_enabled(struct pci_dev *start,
        return true;
 }
 
+/**
+ * pci_acs_init - Initialize ACS if hardware supports it
+ * @dev: the PCI device
+ */
+void pci_acs_init(struct pci_dev *dev)
+{
+       dev->acs_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
+
+       if (dev->acs_cap)
+               pci_enable_acs(dev);
+}
+
 /**
  * pci_rebar_find_pos - find position of resize ctrl reg for BAR
  * @pdev: PCI device
@@ -5688,6 +5708,7 @@ EXPORT_SYMBOL(pcie_get_readrq);
 int pcie_set_readrq(struct pci_dev *dev, int rq)
 {
        u16 v;
+       int ret;
 
        if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
                return -EINVAL;
@@ -5706,8 +5727,10 @@ int pcie_set_readrq(struct pci_dev *dev, int rq)
 
        v = (ffs(rq) - 8) << 12;
 
-       return pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
+       ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
                                                  PCI_EXP_DEVCTL_READRQ, v);
+
+       return pcibios_err_to_errno(ret);
 }
 EXPORT_SYMBOL(pcie_set_readrq);
 
@@ -5738,6 +5761,7 @@ EXPORT_SYMBOL(pcie_get_mps);
 int pcie_set_mps(struct pci_dev *dev, int mps)
 {
        u16 v;
+       int ret;
 
        if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
                return -EINVAL;
@@ -5747,8 +5771,10 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
                return -EINVAL;
        v <<= 5;
 
-       return pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
+       ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
                                                  PCI_EXP_DEVCTL_PAYLOAD, v);
+
+       return pcibios_err_to_errno(ret);
 }
 EXPORT_SYMBOL(pcie_set_mps);
 
index 6d3f758..42b95db 100644 (file)
@@ -92,6 +92,7 @@ void pci_refresh_power_state(struct pci_dev *dev);
 int pci_power_up(struct pci_dev *dev);
 void pci_disable_enabled_device(struct pci_dev *dev);
 int pci_finish_runtime_suspend(struct pci_dev *dev);
+void pcie_clear_device_status(struct pci_dev *dev);
 void pcie_clear_root_pme_status(struct pci_dev *dev);
 bool pci_check_pme_status(struct pci_dev *dev);
 void pci_pme_wakeup_bus(struct pci_bus *bus);
@@ -532,7 +533,7 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
        return resource_alignment(res);
 }
 
-void pci_enable_acs(struct pci_dev *dev);
+void pci_acs_init(struct pci_dev *dev);
 #ifdef CONFIG_PCI_QUIRKS
 int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
 int pci_dev_specific_enable_acs(struct pci_dev *dev);
@@ -555,7 +556,7 @@ static inline int pci_dev_specific_disable_acs_redir(struct pci_dev *dev)
 
 /* PCI error reporting and recovery */
 pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
-                       enum pci_channel_state state,
+                       pci_channel_state_t state,
                        pci_ers_result_t (*reset_link)(struct pci_dev *pdev));
 
 bool pcie_wait_for_link(struct pci_dev *pdev, bool active);
@@ -658,7 +659,6 @@ void pci_aer_init(struct pci_dev *dev);
 void pci_aer_exit(struct pci_dev *dev);
 extern const struct attribute_group aer_stats_attr_group;
 void pci_aer_clear_fatal_status(struct pci_dev *dev);
-void pci_aer_clear_device_status(struct pci_dev *dev);
 int pci_aer_clear_status(struct pci_dev *dev);
 int pci_aer_raw_clear_status(struct pci_dev *dev);
 #else
@@ -666,7 +666,6 @@ static inline void pci_no_aer(void) { }
 static inline void pci_aer_init(struct pci_dev *d) { }
 static inline void pci_aer_exit(struct pci_dev *d) { }
 static inline void pci_aer_clear_fatal_status(struct pci_dev *dev) { }
-static inline void pci_aer_clear_device_status(struct pci_dev *dev) { }
 static inline int pci_aer_clear_status(struct pci_dev *dev) { return -EINVAL; }
 static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL; }
 #endif
index 9cd3133..3946555 100644 (file)
@@ -43,7 +43,7 @@ config PCIEAER_INJECT
          error injection can fake almost all kinds of errors with the
          help of a user space helper tool aer-inject, which can be
          gotten from:
-            http://www.kernel.org/pub/linux/utils/pci/aer-inject/
+            https://www.kernel.org/pub/linux/utils/pci/aer-inject/
 
 #
 # PCI Express ECRC
index 3acf566..87283cd 100644 (file)
@@ -224,31 +224,28 @@ int pcie_aer_is_native(struct pci_dev *dev)
 
 int pci_enable_pcie_error_reporting(struct pci_dev *dev)
 {
+       int rc;
+
        if (!pcie_aer_is_native(dev))
                return -EIO;
 
-       return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
+       rc = pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
+       return pcibios_err_to_errno(rc);
 }
 EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
 
 int pci_disable_pcie_error_reporting(struct pci_dev *dev)
 {
+       int rc;
+
        if (!pcie_aer_is_native(dev))
                return -EIO;
 
-       return pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
-                                         PCI_EXP_AER_FLAGS);
+       rc = pcie_capability_clear_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
+       return pcibios_err_to_errno(rc);
 }
 EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
 
-void pci_aer_clear_device_status(struct pci_dev *dev)
-{
-       u16 sta;
-
-       pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &sta);
-       pcie_capability_write_word(dev, PCI_EXP_DEVSTA, sta);
-}
-
 int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
 {
        int aer = dev->aer_cap;
@@ -447,7 +444,7 @@ static const char *aer_error_layer[] = {
        "Transaction Layer"
 };
 
-static const char *aer_correctable_error_string[AER_MAX_TYPEOF_COR_ERRS] = {
+static const char *aer_correctable_error_string[] = {
        "RxErr",                        /* Bit Position 0       */
        NULL,
        NULL,
@@ -464,9 +461,25 @@ static const char *aer_correctable_error_string[AER_MAX_TYPEOF_COR_ERRS] = {
        "NonFatalErr",                  /* Bit Position 13      */
        "CorrIntErr",                   /* Bit Position 14      */
        "HeaderOF",                     /* Bit Position 15      */
+       NULL,                           /* Bit Position 16      */
+       NULL,                           /* Bit Position 17      */
+       NULL,                           /* Bit Position 18      */
+       NULL,                           /* Bit Position 19      */
+       NULL,                           /* Bit Position 20      */
+       NULL,                           /* Bit Position 21      */
+       NULL,                           /* Bit Position 22      */
+       NULL,                           /* Bit Position 23      */
+       NULL,                           /* Bit Position 24      */
+       NULL,                           /* Bit Position 25      */
+       NULL,                           /* Bit Position 26      */
+       NULL,                           /* Bit Position 27      */
+       NULL,                           /* Bit Position 28      */
+       NULL,                           /* Bit Position 29      */
+       NULL,                           /* Bit Position 30      */
+       NULL,                           /* Bit Position 31      */
 };
 
-static const char *aer_uncorrectable_error_string[AER_MAX_TYPEOF_UNCOR_ERRS] = {
+static const char *aer_uncorrectable_error_string[] = {
        "Undefined",                    /* Bit Position 0       */
        NULL,
        NULL,
@@ -494,6 +507,11 @@ static const char *aer_uncorrectable_error_string[AER_MAX_TYPEOF_UNCOR_ERRS] = {
        "AtomicOpBlocked",              /* Bit Position 24      */
        "TLPBlockedErr",                /* Bit Position 25      */
        "PoisonTLPBlocked",             /* Bit Position 26      */
+       NULL,                           /* Bit Position 27      */
+       NULL,                           /* Bit Position 28      */
+       NULL,                           /* Bit Position 29      */
+       NULL,                           /* Bit Position 30      */
+       NULL,                           /* Bit Position 31      */
 };
 
 static const char *aer_agent_string[] = {
@@ -650,24 +668,26 @@ static void __print_tlp_header(struct pci_dev *dev,
 static void __aer_print_error(struct pci_dev *dev,
                              struct aer_err_info *info)
 {
+       const char **strings;
        unsigned long status = info->status & ~info->mask;
-       const char *errmsg = NULL;
+       const char *level, *errmsg;
        int i;
 
+       if (info->severity == AER_CORRECTABLE) {
+               strings = aer_correctable_error_string;
+               level = KERN_WARNING;
+       } else {
+               strings = aer_uncorrectable_error_string;
+               level = KERN_ERR;
+       }
+
        for_each_set_bit(i, &status, 32) {
-               if (info->severity == AER_CORRECTABLE)
-                       errmsg = i < ARRAY_SIZE(aer_correctable_error_string) ?
-                               aer_correctable_error_string[i] : NULL;
-               else
-                       errmsg = i < ARRAY_SIZE(aer_uncorrectable_error_string) ?
-                               aer_uncorrectable_error_string[i] : NULL;
+               errmsg = strings[i];
+               if (!errmsg)
+                       errmsg = "Unknown Error Bit";
 
-               if (errmsg)
-                       pci_err(dev, "   [%2d] %-22s%s\n", i, errmsg,
+               pci_printk(level, dev, "   [%2d] %-22s%s\n", i, errmsg,
                                info->first_error == i ? " (First)" : "");
-               else
-                       pci_err(dev, "   [%2d] Unknown Error Bit%s\n",
-                               i, info->first_error == i ? " (First)" : "");
        }
        pci_dev_aer_stats_incr(dev, info);
 }
@@ -676,6 +696,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
 {
        int layer, agent;
        int id = ((dev->bus->number << 8) | dev->devfn);
+       const char *level;
 
        if (!info->status) {
                pci_err(dev, "PCIe Bus Error: severity=%s, type=Inaccessible, (Unregistered Agent ID)\n",
@@ -686,13 +707,14 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
        layer = AER_GET_LAYER_ERROR(info->severity, info->status);
        agent = AER_GET_AGENT(info->severity, info->status);
 
-       pci_err(dev, "PCIe Bus Error: severity=%s, type=%s, (%s)\n",
-               aer_error_severity_string[info->severity],
-               aer_error_layer[layer], aer_agent_string[agent]);
+       level = (info->severity == AER_CORRECTABLE) ? KERN_WARNING : KERN_ERR;
+
+       pci_printk(level, dev, "PCIe Bus Error: severity=%s, type=%s, (%s)\n",
+                  aer_error_severity_string[info->severity],
+                  aer_error_layer[layer], aer_agent_string[agent]);
 
-       pci_err(dev, "  device [%04x:%04x] error status/mask=%08x/%08x\n",
-               dev->vendor, dev->device,
-               info->status, info->mask);
+       pci_printk(level, dev, "  device [%04x:%04x] error status/mask=%08x/%08x\n",
+                  dev->vendor, dev->device, info->status, info->mask);
 
        __aer_print_error(dev, info);
 
@@ -922,7 +944,8 @@ static void handle_error_source(struct pci_dev *dev, struct aer_err_info *info)
                if (aer)
                        pci_write_config_dword(dev, aer + PCI_ERR_COR_STATUS,
                                        info->status);
-               pci_aer_clear_device_status(dev);
+               if (pcie_aer_is_native(dev))
+                       pcie_clear_device_status(dev);
        } else if (info->severity == AER_NONFATAL)
                pcie_do_recovery(dev, pci_channel_io_normal, aer_root_reset);
        else if (info->severity == AER_FATAL)
index 21cc3d3..c2cbf42 100644 (file)
@@ -6,7 +6,7 @@
  * trigger various real hardware errors. Software based error
  * injection can fake almost all kinds of errors with the help of a
  * user space helper tool aer-inject, which can be gotten from:
- *   http://www.kernel.org/pub/linux/utils/pci/aer-inject/
+ *   https://www.kernel.org/pub/linux/utils/pci/aer-inject/
  *
  * Copyright 2009 Intel Corporation.
  *     Huang Ying <ying.huang@intel.com>
index b17e5ff..253c30c 100644 (file)
@@ -1182,6 +1182,7 @@ static int pcie_aspm_get_policy(char *buffer, const struct kernel_param *kp)
                        cnt += sprintf(buffer + cnt, "[%s] ", policy_str[i]);
                else
                        cnt += sprintf(buffer + cnt, "%s ", policy_str[i]);
+       cnt += sprintf(buffer + cnt, "\n");
        return cnt;
 }
 
index 14bb8f5..c543f41 100644 (file)
@@ -46,7 +46,7 @@ static pci_ers_result_t merge_result(enum pci_ers_result orig,
 }
 
 static int report_error_detected(struct pci_dev *dev,
-                                enum pci_channel_state state,
+                                pci_channel_state_t state,
                                 enum pci_ers_result *result)
 {
        pci_ers_result_t vote;
@@ -147,7 +147,7 @@ out:
 }
 
 pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
-                       enum pci_channel_state state,
+                       pci_channel_state_t state,
                        pci_ers_result_t (*reset_link)(struct pci_dev *pdev))
 {
        pci_ers_result_t status = PCI_ERS_RESULT_CAN_RECOVER;
@@ -197,7 +197,8 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
        pci_dbg(dev, "broadcast resume message\n");
        pci_walk_bus(bus, report_resume, &status);
 
-       pci_aer_clear_device_status(dev);
+       if (pcie_aer_is_native(dev))
+               pcie_clear_device_status(dev);
        pci_aer_clear_nonfatal_status(dev);
        pci_info(dev, "device recovery successful\n");
        return status;
index 3acf151..3a3ce40 100644 (file)
@@ -146,7 +146,7 @@ static void pcie_portdrv_remove(struct pci_dev *dev)
 }
 
 static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
-                                       enum pci_channel_state error)
+                                       pci_channel_state_t error)
 {
        /* Root Port has no impact. Always recovers. */
        return PCI_ERS_RESULT_CAN_RECOVER;
index 2f66988..494333d 100644 (file)
@@ -1552,7 +1552,7 @@ static void set_pcie_untrusted(struct pci_dev *dev)
         * untrusted as well.
         */
        parent = pci_upstream_bridge(dev);
-       if (parent && parent->untrusted)
+       if (parent && (parent->untrusted || parent->external_facing))
                dev->untrusted = true;
 }
 
@@ -1802,9 +1802,6 @@ int pci_setup_device(struct pci_dev *dev)
        dev->revision = class & 0xff;
        dev->class = class >> 8;                    /* upper 3 bytes */
 
-       pci_info(dev, "[%04x:%04x] type %02x class %#08x\n",
-                  dev->vendor, dev->device, dev->hdr_type, dev->class);
-
        if (pci_early_dump)
                early_dump_pci_device(dev);
 
@@ -1822,6 +1819,9 @@ int pci_setup_device(struct pci_dev *dev)
        /* Early fixups, before probing the BARs */
        pci_fixup_device(pci_fixup_early, dev);
 
+       pci_info(dev, "[%04x:%04x] type %02x class %#08x\n",
+                dev->vendor, dev->device, dev->hdr_type, dev->class);
+
        /* Device class may be changed after fixup */
        class = dev->class >> 8;
 
@@ -2390,7 +2390,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
        pci_ats_init(dev);              /* Address Translation Services */
        pci_pri_init(dev);              /* Page Request Interface */
        pci_pasid_init(dev);            /* Process Address Space ID */
-       pci_enable_acs(dev);            /* Enable ACS P2P upstream forwarding */
+       pci_acs_init(dev);              /* Access Control Services */
        pci_ptm_init(dev);              /* Precision Time Measurement */
        pci_aer_init(dev);              /* Advanced Error Reporting */
        pci_dpc_init(dev);              /* Downstream Port Containment */
index 2456a19..a81315e 100644 (file)
@@ -3549,7 +3549,7 @@ static void quirk_no_bus_reset(struct pci_dev *dev)
  * The device will throw a Link Down error on AER-capable systems and
  * regardless of AER, config space of the device is never accessible again
  * and typically causes the system to hang or reset when access is attempted.
- * http://www.spinics.net/lists/linux-pci/msg34797.html
+ * https://lore.kernel.org/r/20140923210318.498dacbd@dualc.maya.org/
  */
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset);
@@ -4378,9 +4378,9 @@ static int pci_acs_ctrl_enabled(u16 acs_ctrl_req, u16 acs_ctrl_ena)
  * redirect (CR) since all transactions are redirected to the upstream
  * root complex.
  *
- * http://permalink.gmane.org/gmane.comp.emulators.kvm.devel/94086
- * http://permalink.gmane.org/gmane.comp.emulators.kvm.devel/94102
- * http://permalink.gmane.org/gmane.comp.emulators.kvm.devel/99402
+ * https://lore.kernel.org/r/201207111426.q6BEQTbh002928@mail.maya.org/
+ * https://lore.kernel.org/r/20120711165854.GM25282@amd.com/
+ * https://lore.kernel.org/r/20121005130857.GX4009@amd.com/
  *
  * 1002:4385 SBx00 SMBus Controller
  * 1002:439c SB7x0/SB8x0/SB9x0 IDE Controller
@@ -4622,11 +4622,11 @@ static int pci_quirk_al_acs(struct pci_dev *dev, u16 acs_flags)
  *
  * 0x9d10-0x9d1b PCI Express Root port #{1-12}
  *
- * [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
- * [4] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-spec-update.html
- * [5] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-datasheet-vol-1.html
+ * [1] https://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html
+ * [2] https://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html
+ * [3] https://www.intel.com/content/www/us/en/chipsets/100-series-chipset-spec-update.html
+ * [4] https://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-spec-update.html
+ * [5] https://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-datasheet-vol-1.html
  * [6] https://www.intel.com/content/www/us/en/processors/core/7th-gen-core-family-mobile-u-y-processor-lines-i-o-spec-update.html
  * [7] https://www.intel.com/content/www/us/en/processors/core/7th-gen-core-family-mobile-u-y-processor-lines-i-o-datasheet-vol-1.html
  */
@@ -4655,7 +4655,7 @@ static int pci_quirk_intel_spt_pch_acs(struct pci_dev *dev, u16 acs_flags)
        if (!pci_quirk_intel_spt_pch_acs_match(dev))
                return -ENOTTY;
 
-       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
+       pos = dev->acs_cap;
        if (!pos)
                return -ENOTTY;
 
@@ -4963,7 +4963,7 @@ static int pci_quirk_enable_intel_spt_pch_acs(struct pci_dev *dev)
        if (!pci_quirk_intel_spt_pch_acs_match(dev))
                return -ENOTTY;
 
-       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
+       pos = dev->acs_cap;
        if (!pos)
                return -ENOTTY;
 
@@ -4990,7 +4990,7 @@ static int pci_quirk_disable_intel_spt_pch_acs_redir(struct pci_dev *dev)
        if (!pci_quirk_intel_spt_pch_acs_match(dev))
                return -ENOTTY;
 
-       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
+       pos = dev->acs_cap;
        if (!pos)
                return -ENOTTY;
 
@@ -5360,7 +5360,7 @@ int pci_idt_bus_quirk(struct pci_bus *bus, int devfn, u32 *l, int timeout)
        bool found;
        struct pci_dev *bridge = bus->self;
 
-       pos = pci_find_ext_capability(bridge, PCI_EXT_CAP_ID_ACS);
+       pos = bridge->acs_cap;
 
        /* Disable ACS SV before initial config reads */
        if (pos) {
index 9b94b1f..4d870ed 100644 (file)
@@ -152,7 +152,7 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
 
                tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
                if (!tmp)
-                       panic("pdev_sort_resources(): kmalloc() failed!\n");
+                       panic("%s: kzalloc() failed!\n", __func__);
                tmp->res = r;
                tmp->dev = dev;
 
index d21fa04..43eda10 100644 (file)
@@ -73,7 +73,8 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
                /*
                 * Apparently some Matrox devices have ROM BARs that read
                 * as zero when disabled, so don't update ROM BARs unless
-                * they're enabled.  See https://lkml.org/lkml/2005/8/30/138.
+                * they're enabled.  See
+                * https://lore.kernel.org/r/43147B3D.1030309@vc.cvut.cz/
                 */
                if (!(res->flags & IORESOURCE_ROM_ENABLE))
                        return;
index cc386ef..3861505 100644 (file)
@@ -268,13 +268,16 @@ placeholder:
        slot_name = make_slot_name(name);
        if (!slot_name) {
                err = -ENOMEM;
+               kfree(slot);
                goto err;
        }
 
        err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL,
                                   "%s", slot_name);
-       if (err)
+       if (err) {
+               kobject_put(&slot->kobj);
                goto err;
+       }
 
        INIT_LIST_HEAD(&slot->list);
        list_add(&slot->list, &parent->slots);
@@ -293,7 +296,6 @@ out:
        mutex_unlock(&pci_slot_mutex);
        return slot;
 err:
-       kfree(slot);
        slot = ERR_PTR(err);
        goto out;
 }
index a308e86..37f6560 100644 (file)
@@ -2002,7 +2002,7 @@ static void aac_remove_one(struct pci_dev *pdev)
 }
 
 static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev,
-                                       enum pci_channel_state error)
+                                       pci_channel_state_t error)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct aac_dev *aac = shost_priv(shost);
index cd157f1..bd38c8c 100644 (file)
@@ -7423,8 +7423,12 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info)
 static inline int pqi_set_pcie_completion_timeout(struct pci_dev *pci_dev,
        u16 timeout)
 {
-       return pcie_capability_clear_and_set_word(pci_dev, PCI_EXP_DEVCTL2,
+       int rc;
+
+       rc = pcie_capability_clear_and_set_word(pci_dev, PCI_EXP_DEVCTL2,
                PCI_EXP_DEVCTL2_COMP_TIMEOUT, timeout);
+
+       return pcibios_err_to_errno(rc);
 }
 
 static int pqi_pci_init(struct pqi_ctrl_info *ctrl_info)
index 2ca018c..f455243 100644 (file)
@@ -1743,7 +1743,7 @@ static void sym2_remove(struct pci_dev *pdev)
  * @state: current state of the PCI slot
  */
 static pci_ers_result_t sym2_io_error_detected(struct pci_dev *pdev,
-                                         enum pci_channel_state state)
+                                         pci_channel_state_t state)
 {
        /* If slot is permanently frozen, turn everything off */
        if (state == pci_channel_io_perm_failure) {
index 402edae..ac30aef 100644 (file)
@@ -4678,7 +4678,7 @@ static void ql_eeh_close(struct net_device *ndev)
  * a PCI bus error is detected.
  */
 static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev,
-                                              enum pci_channel_state state)
+                                              pci_channel_state_t state)
 {
        struct net_device *ndev = pci_get_drvdata(pdev);
        struct ql_adapter *qdev = netdev_priv(ndev);
index c79d833..6ebde53 100644 (file)
@@ -179,7 +179,7 @@ static inline const char *pci_power_name(pci_power_t state)
  */
 typedef unsigned int __bitwise pci_channel_state_t;
 
-enum pci_channel_state {
+enum {
        /* I/O channel is in normal state */
        pci_channel_io_normal = (__force pci_channel_state_t) 1,
 
@@ -432,6 +432,12 @@ struct pci_dev {
         * mappings to make sure they cannot access arbitrary memory.
         */
        unsigned int    untrusted:1;
+       /*
+        * Info from the platform, e.g., ACPI or device tree, may mark a
+        * device as "external-facing".  An external-facing device is
+        * itself internal but devices downstream from it are external.
+        */
+       unsigned int    external_facing:1;
        unsigned int    broken_intx_masking:1;  /* INTx masking can't be used */
        unsigned int    io_window_1k:1;         /* Intel bridge 1K I/O windows */
        unsigned int    irq_managed:1;
@@ -486,6 +492,7 @@ struct pci_dev {
 #ifdef CONFIG_PCI_P2PDMA
        struct pci_p2pdma *p2pdma;
 #endif
+       u16             acs_cap;        /* ACS Capability offset */
        phys_addr_t     rom;            /* Physical address if not from BAR */
        size_t          romlen;         /* Length if not from BAR */
        char            *driver_override; /* Driver name to force a match */
@@ -785,7 +792,7 @@ enum pci_ers_result {
 struct pci_error_handlers {
        /* PCI bus error detected on this device */
        pci_ers_result_t (*error_detected)(struct pci_dev *dev,
-                                          enum pci_channel_state error);
+                                          pci_channel_state_t error);
 
        /* MMIO has been re-enabled, but not DMA */
        pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev);
@@ -1053,13 +1060,6 @@ void pci_sort_breadthfirst(void);
 
 /* Generic PCI functions exported to card drivers */
 
-enum pci_lost_interrupt_reason {
-       PCI_LOST_IRQ_NO_INFORMATION = 0,
-       PCI_LOST_IRQ_DISABLE_MSI,
-       PCI_LOST_IRQ_DISABLE_MSIX,
-       PCI_LOST_IRQ_DISABLE_ACPI,
-};
-enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *dev);
 int pci_find_capability(struct pci_dev *dev, int cap);
 int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap);
 int pci_find_ext_capability(struct pci_dev *dev, int cap);
index 0ad5769..5c709a1 100644 (file)
 
 #define PCI_VENDOR_ID_ASMEDIA          0x1b21
 
+#define PCI_VENDOR_ID_REDHAT           0x1b36
+
 #define PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS    0x1c36
 
 #define PCI_VENDOR_ID_CIRCUITCO                0x1cc8
index eb26421..961c55e 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /* pci ids */
-#define MDPY_PCI_VENDOR_ID     0x1b36 /* redhat */
+#define MDPY_PCI_VENDOR_ID     PCI_VENDOR_ID_REDHAT
 #define MDPY_PCI_DEVICE_ID     0x000f
 #define MDPY_PCI_SUBVENDOR_ID  PCI_SUBVENDOR_ID_REDHAT_QUMRANET
 #define MDPY_PCI_SUBDEVICE_ID  PCI_SUBDEVICE_ID_QEMU