Commit Graph

869 Commits

Author SHA1 Message Date
Bjorn Helgaas
034f93fcb1 Merge branch 'pci/pm'
- Cache the PTM capability offset instead of searching for it every time
  (Bjorn Helgaas)

- Separate PTM configuration from PTM enable (Bjorn Helgaas)

- Add pci_suspend_ptm() and pci_resume_ptm() to disable and re-enable PTM
  on suspend/resume so some Root Ports can safely enter a lower-power PM
  state (Bjorn Helgaas)

- Disable PTM for all devices during suspend; previously we only did this
  for Root Ports and even then only in certain cases (Bjorn Helgaas)

- Simplify pci_pm_suspend_noirq() (Rajvi Jingar)

- Reduce the delay after transitions to/from D3hot by using usleep_range()
  instead of msleep(), which reduces the typical delay from 19ms to 10ms
  (Sajid Dalvi, Will McVicker)

* pci/pm:
  PCI/PM: Reduce D3hot delay with usleep_range()
  PCI/PM: Simplify pci_pm_suspend_noirq()
  PCI/PM: Always disable PTM for all devices during suspend
  PCI/PTM: Consolidate PTM interface declarations
  PCI/PTM: Reorder functions in logical order
  PCI/PTM: Preserve RsvdP bits in PTM Control register
  PCI/PTM: Move pci_ptm_info() body into its only caller
  PCI/PTM: Add pci_suspend_ptm() and pci_resume_ptm()
  PCI/PTM: Separate configuration and enable
  PCI/PTM: Add pci_upstream_ptm() helper
  PCI/PTM: Cache PTM Capability offset
2022-10-05 17:32:53 -05:00
Bjorn Helgaas
f9538e27a2 Merge branch 'pci/dpc'
- Work around a BIOS defect that makes some Intel Root Ports report an RP
  PIO log size of zero (Mika Westerberg)

* pci/dpc:
  PCI/DPC: Quirk PIO log size for certain Intel Root Ports
2022-10-05 17:32:52 -05:00
Bjorn Helgaas
7afeb84d14 PCI/ASPM: Correct LTR_L1.2_THRESHOLD computation
80d7d7a904 ("PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device
characteristics") replaced a fixed value (163840ns) with one computed from
T_POWER_OFF, Common_Mode_Restore_Time, etc., but it encoded the
LTR_L1.2_THRESHOLD value incorrectly.

This is especially a problem for small thresholds, e.g., 63ns fell into the
"threshold_ns < 1024" case and was encoded as 32ns:

  LTR_L1.2_THRESHOLD_Scale = 1 (multiplier is 32ns)
  LTR_L1.2_THRESHOLD_Value = 63 >> 5 = 1
  LTR_L1.2_THRESHOLD       = multiplier * value = 32ns * 1 = 32ns

Correct the algorithm to encode all times of 1023ns (0x3ff) or smaller
exactly and larger times conservatively (the encoded threshold is never
smaller than was requested).  This reduces the chance of entering L1.2
when the device can't tolerate the exit latency.

Fixes: 80d7d7a904 ("PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device characteristics")
Link: https://lore.kernel.org/r/20221005025809.2247547-4-helgaas@kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
2022-10-05 12:12:02 -05:00
Bjorn Helgaas
cfc0028627 PCI/ASPM: Ignore L1 PM Substates if device lacks capability
187f91db82 ("PCI/ASPM: Remove struct aspm_register_info.l1ss_cap")
inadvertently removed a check for existence of the L1 PM Substates (L1SS)
Capability before reading it.

If there is no L1SS Capability, this means we mistakenly read PCI_COMMAND
and PCI_STATUS (config address 0x04) and interpret that as the PCI_L1SS_CAP
register, so we may incorrectly configure L1SS.

Make sure the L1SS Capability exists before trying to read it.

Fixes: 187f91db82 ("PCI/ASPM: Remove struct aspm_register_info.l1ss_cap")
Link: https://lore.kernel.org/r/20221005025809.2247547-3-helgaas@kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
2022-10-05 12:11:56 -05:00
Bjorn Helgaas
9e2a03173d PCI/ASPM: Factor out L1 PM Substates configuration
Move L1 PM Substates configuration from pcie_aspm_cap_init() to a new
aspm_l1ss_init() function.  No functional change intended.

Link: https://lore.kernel.org/r/20221005025809.2247547-2-helgaas@kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
2022-10-05 12:11:46 -05:00
Vidya Sagar
4ff116d0d5 PCI/ASPM: Save L1 PM Substates Capability for suspend/resume
Previously the L1 PM Substates Control Registers (CTL1 and CTL2) weren't
saved and restored during suspend/resume leading to the L1 PM Substates
configuration being lost post-resume.

Save the L1 PM Substates Control Registers so that the configuration is
retained post-resume.

[bhelgaas: drop pci_is_pcie() testing; we can rely on pci_configure_ltr()
having already done that]
Link: https://lore.kernel.org/r/20220913131822.16557-3-vidyas@nvidia.com
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2022-10-04 20:35:40 -05:00
Vidya Sagar
5e85eba6f5 PCI/ASPM: Refactor L1 PM Substates Control Register programming
Refactor the code to extract the common code to program Control
Registers 1 and 2 of the L1 PM Substates capability to a new function
aspm_program_l1ss() and call it for both parent and child devices.

[bhelgaas: squash in update to preserve fields we're not updating from
https://lore.kernel.org/r/36fa13c5-e0f8-022f-77f7-7908e4df98b8@nvidia.com]
Link: https://lore.kernel.org/r/20220913131822.16557-2-vidyas@nvidia.com
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2022-10-04 20:32:39 -05:00
Mika Westerberg
5459c0b704 PCI/DPC: Quirk PIO log size for certain Intel Root Ports
Some Root Ports on Intel Tiger Lake and Alder Lake systems support the RP
Extensions for DPC and the RP PIO Log registers but incorrectly advertise
an RP PIO Log Size of zero.  This means the kernel complains that:

  DPC: RP PIO log size 0 is invalid

and if DPC is triggered, the DPC driver will not dump the RP PIO Log
registers when it should.

This is caused by a BIOS bug and should be fixed the BIOS for future CPUs.

Add a quirk to set the correct RP PIO Log size for the affected Root Ports.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=209943
Link: https://lore.kernel.org/r/20220816102042.69125-1-mika.westerberg@linux.intel.com
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
2022-09-27 18:13:18 -05:00
Bjorn Helgaas
8b367e75ac PCI/PTM: Reorder functions in logical order
pci_enable_ptm() and pci_disable_ptm() were separated.
pci_save_ptm_state() and pci_restore_ptm_state() dangled at the top.  Move
them to logical places.  No functional change intended.

Link: https://lore.kernel.org/r/20220909202505.314195-8-helgaas@kernel.org
Tested-by: Rajvi Jingar <rajvi.jingar@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2022-09-12 15:29:52 -05:00
Bjorn Helgaas
2b89c22f24 PCI/PTM: Preserve RsvdP bits in PTM Control register
Even though only the low 16 bits of PTM Control are currently defined, the
register is 32 bits wide and the unused bits are RsvdP ("Reserved and
Preserved"), so software must preserve the values of those bits when
writing the register.

Update PTM Control reads and writes to use 32-bit accesses and preserve the
reserved bits on writes.

Link: https://lore.kernel.org/r/20220909202505.314195-7-helgaas@kernel.org
Tested-by: Rajvi Jingar <rajvi.jingar@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2022-09-12 15:29:47 -05:00
Bjorn Helgaas
91b12b2a10 PCI/PTM: Move pci_ptm_info() body into its only caller
pci_ptm_info() is simple and is only called by pci_enable_ptm().  Move the
entire body there.  No functional change intended.

Link: https://lore.kernel.org/r/20220909202505.314195-6-helgaas@kernel.org
Tested-by: Rajvi Jingar <rajvi.jingar@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2022-09-12 15:29:42 -05:00
Bjorn Helgaas
e8bdc5ea48 PCI/PTM: Add pci_suspend_ptm() and pci_resume_ptm()
We disable PTM during suspend because that allows some Root Ports to enter
lower-power PM states, which means we also need to disable PTM for all
downstream devices.  Add pci_suspend_ptm() and pci_resume_ptm() for this
purpose.

pci_enable_ptm() and pci_disable_ptm() are for drivers to use to enable or
disable PTM.  They use dev->ptm_enabled to keep track of whether PTM should
be enabled.

pci_suspend_ptm() and pci_resume_ptm() are PCI core-internal functions to
temporarily disable PTM during suspend and (depending on dev->ptm_enabled)
re-enable PTM during resume.

Enable/disable/suspend/resume all use internal __pci_enable_ptm() and
__pci_disable_ptm() functions that only update the PTM Control register.
Outline:

  pci_enable_ptm(struct pci_dev *dev)
  {
     __pci_enable_ptm(dev);
     dev->ptm_enabled = 1;
     pci_ptm_info(dev);
  }

  pci_disable_ptm(struct pci_dev *dev)
  {
     if (dev->ptm_enabled) {
       __pci_disable_ptm(dev);
       dev->ptm_enabled = 0;
     }
  }

  pci_suspend_ptm(struct pci_dev *dev)
  {
     if (dev->ptm_enabled)
       __pci_disable_ptm(dev);
  }

  pci_resume_ptm(struct pci_dev *dev)
  {
     if (dev->ptm_enabled)
       __pci_enable_ptm(dev);
  }

Nothing currently calls pci_resume_ptm(); the suspend path saves the PTM
state before disabling PTM, so the PTM state restore in the resume path
implicitly re-enables it.  A future change will use pci_resume_ptm() to fix
some problems with this approach.

Link: https://lore.kernel.org/r/20220909202505.314195-5-helgaas@kernel.org
Tested-by: Rajvi Jingar <rajvi.jingar@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2022-09-12 15:29:37 -05:00
Bjorn Helgaas
118b9dfdc1 PCI/PTM: Separate configuration and enable
PTM configuration and enabling were previously mixed together:
pci_ptm_init() collected granularity info and enabled PTM for Root Ports
and Switch Upstream Ports; pci_enable_ptm() did the same for Endpoints.

Move everything related to the PTM Capability register to pci_ptm_init()
for all devices, and everything related to the PTM Control register to
pci_enable_ptm().

Link: https://lore.kernel.org/r/20220909202505.314195-4-helgaas@kernel.org
Tested-by: Rajvi Jingar <rajvi.jingar@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2022-09-12 15:29:32 -05:00
Bjorn Helgaas
e243c173c0 PCI/PTM: Add pci_upstream_ptm() helper
PTM requires an unbroken path of PTM-supporting devices between the PTM
Root and the ultimate PTM Requester, but if a Switch supports PTM, only the
Upstream Port can have a PTM Capability; the Downstream Ports do not.

Previously we copied the PTM configuration from the Switch Upstream Port to
the Downstream Ports so dev->ptm_enabled for any device implied that all
the upstream devices support PTM.

Instead of making it look like Downstream Ports have their own PTM config,
add pci_upstream_ptm(), which returns the upstream device that has a PTM
Capability (either a Root Port or a Switch Upstream Port).

Link: https://lore.kernel.org/r/20220909202505.314195-3-helgaas@kernel.org
Tested-by: Rajvi Jingar <rajvi.jingar@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2022-09-12 15:29:25 -05:00
Bjorn Helgaas
a47126ec29 PCI/PTM: Cache PTM Capability offset
Cache the PTM Capability offset instead of searching for it every time we
enable/disable PTM or save/restore PTM state.  No functional change
intended.

Link: https://lore.kernel.org/r/20220909202505.314195-2-helgaas@kernel.org
Tested-by: Rajvi Jingar <rajvi.jingar@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2022-09-12 15:28:43 -05:00
Bjorn Helgaas
5a20930f27 Merge branch 'pci/err'
- Recognize disconnected devices so we don't bother trying to set them to
  "frozen" or "normal" state (Christoph Hellwig)

- Clear PCI Status register during enumeration in case firmware left errors
  logged (Kai-Heng Feng)

- Configure ECRC for every device, including hot-added ones (Stefan Roese)

- Keep AER error reporting enabled for switches (Stefan Roese)

- Enable error reporting for all devices that support AER (Stefan Roese)

- Iterate over error counters instead of error strings to avoid printing
  junk in AER sysfs counters (Mohamed Khalfella)

* pci/err:
  PCI/AER: Iterate over error counters instead of error strings
  PCI/AER: Enable error reporting when AER is native
  PCI/portdrv: Don't disable AER reporting in get_port_device_capability()
  PCI/AER: Configure ECRC for every device
  PCI: Clear PCI_STATUS when setting up device
  PCI/ERR: Recognize disconnected devices in report_error_detected()
2022-08-04 11:41:52 -05:00
Mohamed Khalfella
5e6ae05095 PCI/AER: Iterate over error counters instead of error strings
Previously we iterated over AER stat *names*, e.g.,
aer_correctable_error_string[32], but the actual stat *counters* may not be
that large, e.g., pdev->aer_stats->dev_cor_errs[16], which means that we
printed junk in the sysfs stats files.

Iterate over the stat counter arrays instead of the names to avoid this
junk.

Also, added a build time check to make sure all
counters have entries in strings array.

Fixes: 0678e3109a ("PCI/AER: Simplify __aer_print_error()")
Link: https://lore.kernel.org/r/20220509181441.31884-1-mkhalfella@purestorage.com
Reported-by: Meeta Saggi <msaggi@purestorage.com>
Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Meeta Saggi <msaggi@purestorage.com>
Reviewed-by: Eric Badger <ebadger@purestorage.com>
Cc: stable@vger.kernel.org
2022-07-13 14:45:20 -05:00
Stefan Roese
f26e58bf6f PCI/AER: Enable error reporting when AER is native
If we have native control of AER, set the following error reporting enable
bits:

  - Correctable Error Reporting Enable
  - Non-Fatal Error Reporting Enable
  - Fatal Error Reporting Enable
  - Unsupported Request Reporting Enable

Note that these bits are all in the Device Control register and are not
AER-specific.

This affects all devices with an AER capability, including hot-added
devices.

Please note that this change is quite invasive, as error reporting now will
be enabled for all available PCIe Endpoints, which was previously not the
case.

When "pci=noaer" is selected, error reporting stays disabled of course.

[bhelgaas: commit log, note error reporting is not AER-specific]
Link: https://lore.kernel.org/r/20220125071820.2247260-4-sr@denx.de
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pali Rohár <pali@kernel.org>
Cc: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Yao Hongbo <yaohongbo@linux.alibaba.com>
Cc: Naveen Naidu <naveennaidu479@gmail.com>
2022-07-13 14:44:12 -05:00
Stefan Roese
8795e182b0 PCI/portdrv: Don't disable AER reporting in get_port_device_capability()
AER reporting is currently disabled in the DevCtl registers of all non Root
Port PCIe devices on systems using pcie_ports_native || host->native_aer,
disabling AER completely in such systems. This is because 2bd50dd800
("PCI: PCIe: Disable PCIe port services during port initialization"), added
a call to pci_disable_pcie_error_reporting() *after* the AER setup was
completed for the PCIe device tree.

Here a longer analysis about the current status of AER enabling /
disabling upon bootup provided by Bjorn:

  pcie_portdrv_probe
    pcie_port_device_register
      get_port_device_capability
        pci_disable_pcie_error_reporting
          clear CERE NFERE FERE URRE               # <-- disable for RP USP DSP
      pcie_device_init
        device_register                            # new AER service device
          aer_probe
            aer_enable_rootport                    # RP only
              set_downstream_devices_error_reporting
                set_device_error_reporting         # self (RP)
                  if (RP || USP || DSP)
                    pci_enable_pcie_error_reporting
                      set CERE NFERE FERE URRE     # <-- enable for RP
                pci_walk_bus
                  set_device_error_reporting
                    if (RP || USP || DSP)
                      pci_enable_pcie_error_reporting
                        set CERE NFERE FERE URRE   # <-- enable for USP DSP

In a typical Root Port -> Endpoint hierarchy, the above:
  - Disables Error Reporting for the Root Port,
  - Enables Error Reporting for the Root Port,
  - Does NOT enable Error Reporting for the Endpoint because it is not a
    Root Port or Switch Port.

In a deeper Root Port -> Upstream Switch Port -> Downstream Switch
Port -> Endpoint hierarchy:
  - Disables Error Reporting for the Root Port,
  - Enables Error Reporting for the Root Port,
  - Enables Error Reporting for both Switch Ports,
  - Does NOT enable Error Reporting for the Endpoint because it is not a
    Root Port or Switch Port,
  - Disables Error Reporting for the Switch Ports when pcie_portdrv_probe()
    claims them.  AER does not re-enable it because these are not Root
    Ports.

Remove this call to pci_disable_pcie_error_reporting() from
get_port_device_capability(), leaving the already enabled AER configuration
intact. With this change, AER is enabled in the Root Port and the PCIe
switch upstream and downstream ports. Only the PCIe Endpoints don't have
AER enabled yet. A follow-up patch will take care of this Endpoint
enabling.

Fixes: 2bd50dd800 ("PCI: PCIe: Disable PCIe port services during port initialization")
Link: https://lore.kernel.org/r/20220125071820.2247260-3-sr@denx.de
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pali Rohár <pali@kernel.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Yao Hongbo <yaohongbo@linux.alibaba.com>
Cc: Naveen Naidu <naveennaidu479@gmail.com>
2022-07-13 14:43:40 -05:00
Bjorn Helgaas
ba13d4575d PCI/ASPM: Unexport pcie_aspm_support_enabled()
pcie_aspm_support_enabled() is used only by the acpi/pci_root.c driver,
which cannot be built as a module, so it does not need to be exported.
Unexport it.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-07-12 13:18:29 -05:00
Kai-Heng Feng
08d0cc5f34 PCI/ASPM: Remove pcie_aspm_pm_state_change()
pcie_aspm_pm_state_change() was introduced at the inception of PCIe ASPM
code, but it can cause some issues. For instance, when ASPM config is
changed via sysfs, those changes won't persist across power state change
because pcie_aspm_pm_state_change() overwrites them.

Also, if the driver restores L1SS [1] after system resume, the restored
state will also be overwritten by pcie_aspm_pm_state_change().

Remove pcie_aspm_pm_state_change().  If there's any hardware that really
needs it to function, a quirk can be used instead.

[1] https://lore.kernel.org/linux-pci/20220201123536.12962-1-vidyas@nvidia.com/
Link: https://lore.kernel.org/r/20220509073639.2048236-1-kai.heng.feng@canonical.com
[bhelgaas: remove additional pcie_aspm_pm_state_change() call in
pci_set_low_power_state(), added by
10aa5377fc ("PCI/PM: Split pci_raw_set_power_state()") and moved by
7957d20145 ("PCI/PM: Relocate pci_set_low_power_state()")]
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2022-07-12 10:08:26 -05:00
Stefan Roese
9ffb98f144 PCI/AER: Configure ECRC for every device
Move pcie_set_ecrc_checking() to pci_aer_init() to make sure that
pcie_set_ecrc_checking() is called for each PCIe device, including
hot-added devices.

Link: https://lore.kernel.org/r/20220125071820.2247260-2-sr@denx.de
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Pali Rohár <pali@kernel.org>
Cc: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Yao Hongbo <yaohongbo@linux.alibaba.com>
Cc: Naveen Naidu <naveennaidu479@gmail.com>
2022-07-11 14:51:42 -05:00
Christoph Hellwig
5e69a33c5c PCI/ERR: Recognize disconnected devices in report_error_detected()
When a device is already unplugged by pciehp by the time the AER handler is
invoked, the PCIe device will already be in the pci_channel_io_perm_failure
state.  In that case simply return PCI_ERS_RESULT_DISCONNECT instead of
trying to do a state transition that will fail.

Also untangle the state transition failure from the lack of methods to
improve the debugging output in case it happens again.

Link: https://lore.kernel.org/r/20220601074024.3481035-1-hch@lst.de
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
2022-06-08 15:08:40 -05:00
Linus Torvalds
e1cbc3b96a IOMMU Updates for Linux v5.19
Including:
 
 	- Intel VT-d driver updates
 	  - Domain force snooping improvement.
 	  - Cleanups, no intentional functional changes.
 
 	- ARM SMMU driver updates
 	  - Add new Qualcomm device-tree compatible strings
 	  - Add new Nvidia device-tree compatible string for Tegra234
 	  - Fix UAF in SMMUv3 shared virtual addressing code
 	  - Force identity-mapped domains for users of ye olde SMMU
 	    legacy binding
 	  - Minor cleanups
 
 	- Patches to fix a BUG_ON in the vfio_iommu_group_notifier
 	  - Groundwork for upcoming iommufd framework
 	  - Introduction of DMA ownership so that an entire IOMMU group
 	    is either controlled by the kernel or by user-space
 
 	- MT8195 and MT8186 support in the Mediatek IOMMU driver
 
 	- Patches to make forcing of cache-coherent DMA more coherent
 	  between IOMMU drivers
 
 	- Fixes for thunderbolt device DMA protection
 
 	- Various smaller fixes and cleanups
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEr9jSbILcajRFYWYyK/BELZcBGuMFAmKWCbUACgkQK/BELZcB
 GuPHmRAAuoH9iK/jrC3SgrqpBfH2iRN7ovIX8dFvgbQWX27lhXF4gvj2/nYdIvPK
 75j/LmdibuzV3Iez4kjbGKNG1AikwK3dKIH21a84f3ctnoamQyL6nMfCVBFaVD/D
 kvPpTHyjbGPNf6KZyWQdkJ5DXD1aoG1DKkBnslH5pTNPqGuNqbcnRTg0YxiJFLBv
 5w2B6jL06XRzunh+Sp1Dbj+po8ROjLRCEU+tdrndO8W/Dyp6+ZNNuxL9/3BM9zMj
 py0M4piFtGnhmJSdym1eeHm7r1YRjkZw+MN+e8NcrcSihmDutEWo7nRRxA5uVaa+
 3O2DNERqCvQUYxfNRUOKwzV8v51GYQHEPhvOe/MLgaEQDmDmlF2dHNGm93eCMdrv
 m1cT011oU7pa4qHomwLyTJxSsR7FzJ37igq/WeY++MBhl+frqfzEQPVxF+W7GLb8
 QvT/+woCPzLVpJbE7s0FUD4nbPd8c1dAz4+HO1DajxILIOTq1bnPIorSjgXODRjq
 yzsiP1rAg0L0PsL7pXn3cPMzNCE//xtOsRsAGmaVv6wBoMLyWVFCU/wjPEdjrSWA
 nXpAuCL84uxCEl/KLYMsg9UhjT6ko7CuKdsybIG9zNIiUau43uSqgTen0xCpYt0i
 m//O/X3tPyxmoLKRW+XVehGOrBZW+qrQny6hk/Zex+6UJQqVMTA=
 =W0hj
 -----END PGP SIGNATURE-----

Merge tag 'iommu-updates-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull iommu updates from Joerg Roedel:

 - Intel VT-d driver updates:
     - Domain force snooping improvement.
     - Cleanups, no intentional functional changes.

 - ARM SMMU driver updates:
     - Add new Qualcomm device-tree compatible strings
     - Add new Nvidia device-tree compatible string for Tegra234
     - Fix UAF in SMMUv3 shared virtual addressing code
     - Force identity-mapped domains for users of ye olde SMMU legacy
       binding
     - Minor cleanups

 - Fix a BUG_ON in the vfio_iommu_group_notifier:
     - Groundwork for upcoming iommufd framework
     - Introduction of DMA ownership so that an entire IOMMU group is
       either controlled by the kernel or by user-space

 - MT8195 and MT8186 support in the Mediatek IOMMU driver

 - Make forcing of cache-coherent DMA more coherent between IOMMU
   drivers

 - Fixes for thunderbolt device DMA protection

 - Various smaller fixes and cleanups

* tag 'iommu-updates-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (88 commits)
  iommu/amd: Increase timeout waiting for GA log enablement
  iommu/s390: Tolerate repeat attach_dev calls
  iommu/vt-d: Remove hard coding PGSNP bit in PASID entries
  iommu/vt-d: Remove domain_update_iommu_snooping()
  iommu/vt-d: Check domain force_snooping against attached devices
  iommu/vt-d: Block force-snoop domain attaching if no SC support
  iommu/vt-d: Size Page Request Queue to avoid overflow condition
  iommu/vt-d: Fold dmar_insert_one_dev_info() into its caller
  iommu/vt-d: Change return type of dmar_insert_one_dev_info()
  iommu/vt-d: Remove unneeded validity check on dev
  iommu/dma: Explicitly sort PCI DMA windows
  iommu/dma: Fix iova map result check bug
  iommu/mediatek: Fix NULL pointer dereference when printing dev_name
  iommu: iommu_group_claim_dma_owner() must always assign a domain
  iommu/arm-smmu: Force identity domains for legacy binding
  iommu/arm-smmu: Support Tegra234 SMMU
  dt-bindings: arm-smmu: Add compatible for Tegra234 SOC
  dt-bindings: arm-smmu: Document nvidia,memory-controller property
  iommu/arm-smmu-qcom: Add SC8280XP support
  dt-bindings: arm-smmu: Add compatible for Qualcomm SC8280XP
  ...
2022-05-31 09:56:54 -07:00
Kuppuswamy Sathyanarayanan
203926da2b PCI/AER: Clear MULTI_ERR_COR/UNCOR_RCV bits
When a Root Port or Root Complex Event Collector receives an error Message
e.g., ERR_COR, it sets PCI_ERR_ROOT_COR_RCV in the Root Error Status
register and logs the Requester ID in the Error Source Identification
register.  If it receives a second ERR_COR Message before software clears
PCI_ERR_ROOT_COR_RCV, hardware sets PCI_ERR_ROOT_MULTI_COR_RCV and the
Requester ID is lost.

In the following scenario, PCI_ERR_ROOT_MULTI_COR_RCV was never cleared:

  - hardware receives ERR_COR message
  - hardware sets PCI_ERR_ROOT_COR_RCV
  - aer_irq() entered
  - aer_irq(): status = pci_read_config_dword(PCI_ERR_ROOT_STATUS)
  - aer_irq(): now status == PCI_ERR_ROOT_COR_RCV
  - hardware receives second ERR_COR message
  - hardware sets PCI_ERR_ROOT_MULTI_COR_RCV
  - aer_irq(): pci_write_config_dword(PCI_ERR_ROOT_STATUS, status)
  - PCI_ERR_ROOT_COR_RCV is cleared; PCI_ERR_ROOT_MULTI_COR_RCV is set
  - aer_irq() entered again
  - aer_irq(): status = pci_read_config_dword(PCI_ERR_ROOT_STATUS)
  - aer_irq(): now status == PCI_ERR_ROOT_MULTI_COR_RCV
  - aer_irq() exits because PCI_ERR_ROOT_COR_RCV not set
  - PCI_ERR_ROOT_MULTI_COR_RCV is still set

The same problem occurred with ERR_NONFATAL/ERR_FATAL Messages and
PCI_ERR_ROOT_UNCOR_RCV and PCI_ERR_ROOT_MULTI_UNCOR_RCV.

Fix the problem by queueing an AER event and clearing the Root Error Status
bits when any of these bits are set:

  PCI_ERR_ROOT_COR_RCV
  PCI_ERR_ROOT_UNCOR_RCV
  PCI_ERR_ROOT_MULTI_COR_RCV
  PCI_ERR_ROOT_MULTI_UNCOR_RCV

See the bugzilla link for details from Eric about how to reproduce this
problem.

[bhelgaas: commit log, move repro details to bugzilla]
Fixes: e167bfcaa4 ("PCI: aerdrv: remove magical ROOT_ERR_STATUS_MASKS")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215992
Link: https://lore.kernel.org/r/20220418150237.1021519-1-sathyanarayanan.kuppuswamy@linux.intel.com
Reported-by: Eric Badger <ebadger@purestorage.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ashok Raj <ashok.raj@intel.com>
2022-05-17 16:30:07 -05:00
Lu Baolu
c7d4698497 PCI: portdrv: Set driver_managed_dma
If a switch lacks ACS P2P Request Redirect, a device below the switch can
bypass the IOMMU and DMA directly to other devices below the switch, so
all the downstream devices must be in the same IOMMU group as the switch
itself.

The existing VFIO framework allows the portdrv driver to be bound to the
bridge while its downstream devices are assigned to user space. The
pci_dma_configure() marks the IOMMU group as containing only devices
with kernel drivers that manage DMA. Avoid this default behavior for the
portdrv driver in order for compatibility with the current VFIO usage.

We achieve this by setting ".driver_managed_dma = true" in pci_driver
structure. It is safe because the portdrv driver meets below criteria:

- This driver doesn't use DMA, as you can't find any related calls like
  pci_set_master() or any kernel DMA API (dma_map_*() and etc.).
- It doesn't use MMIO as you can't find ioremap() or similar calls. It's
  tolerant to userspace possibly also touching the same MMIO registers
  via P2P DMA access.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Suggested-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://lore.kernel.org/r/20220418005000.897664-7-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
2022-04-28 15:32:20 +02:00
Linus Torvalds
148a650476 pci-v5.18-changes
-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCgAyFiEEgMe7l+5h9hnxdsnuWYigwDrT+vwFAmI7iOwUHGJoZWxnYWFz
 QGdvb2dsZS5jb20ACgkQWYigwDrT+vxkuhAAtJkVwfeyUjZ8sms+qWdZaucJmFF1
 PDeKy8O8upLzRRykdWoAOjKKVcCB9ohxBjPMco2oYNTmSozxeau8jjMA9OTQvTOS
 ZhDDoi49/vHRHuq3WIeAMCuk7tH3H1L3f0UHJxJ3H/oObQ+eMsitPcGFK+QrISDX
 pYokOnXZvf7BT7NpVtogSe2mhniOD1zQSicAMiH6WKNHHZcxewrzV9LP3MFOoBAr
 VMhlhzJbOp9spvCt7M1DycJEQ2RNe+wGLBFDalhPuprwnkNchRV+0AwWfD90zc9u
 h/0J8jkXfqS6QfSd/lOlTvI6kGsV8UKZEt4h4X/hlHFebFM5ktD9X7GmcoYUDFd9
 aHV3I/Jf62uGJ31IrT0V/cSYNlMO+IVFwXLGir4B1cFPOkzyIG/i60iV/C6bnnCa
 TCMH6vxalFycYaHBFqw/K/Dlq+mrAX74nQDfbk8y6rprczM1BN220Z8BkpG13TBu
 MxgCEul2/BJmNcPS1IWb/mCfBy+rdrVn2DZuID3J9KTwKNOUTIuAF0FuxLP4Bk4o
 sti3vKIXOcHnAcJB9tEnpEfstPv2JT13eWDIMmp/qCwqcujOvsg/DSYrx+8ogmBF
 DJ/sbPy3BdIOAeTgepWHAxYcv9SlZTGJGl+oaR1zV0qLBogyQUWZ9Ijx5aAEAw3j
 AJicpdk3BkH3LC8=
 =5Q9H
 -----END PGP SIGNATURE-----

Merge tag 'pci-v5.18-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull pci updates from Bjorn Helgaas:
 "Enumeration:
   - Move the VGA arbiter from drivers/gpu to drivers/pci because it's
     PCI-specific, not GPU-specific (Bjorn Helgaas)
   - Select the default VGA device consistently whether it's enumerated
     before or after VGA arbiter init, which fixes arches that enumerate
     PCI devices late (Huacai Chen)

  Resource management:
   - Support BAR sizes up to 8TB (Dongdong Liu)

  PCIe native device hotplug:
   - Fix "Command Completed" tracking to avoid spurious timouts when
     powering off empty slots (Liguang Zhang)
   - Quirk Qualcomm devices that don't implement Command Completed
     correctly, again to avoid spurious timeouts (Manivannan Sadhasivam)

  Peer-to-peer DMA:
   - Add Intel 3rd Gen Intel Xeon Scalable Processors to whitelist
     (Michael J. Ruhl)

  APM X-Gene PCIe controller driver:
   - Revert generic DT parsing changes that broke some machines in the
     field (Marc Zyngier)

  Freescale i.MX6 PCIe controller driver:
   - Allow controller probe to succeed even when no devices currently
     present to allow hot-add later (Fabio Estevam)
   - Enable power management on i.MX6QP (Richard Zhu)
   - Assert CLKREQ# on i.MX8MM so enumeration doesn't hang when no
     device is connected (Richard Zhu)

  Marvell Aardvark PCIe controller driver:
   - Fix MSI and MSI-X support (Marek Behún, Pali Rohár)
   - Add support for ERR and PME interrupts (Pali Rohár)

  Marvell MVEBU PCIe controller driver:
   - Add DT binding and support for "num-lanes" (Pali Rohár)
   - Add support for INTx interrupts (Pali Rohár)

  Microsoft Hyper-V host bridge driver:
   - Avoid unnecessary hypercalls when unmasking IRQs on ARM64 (Boqun
     Feng)

  Qualcomm PCIe controller driver:
   - Add SM8450 DT binding and driver support (Dmitry Baryshkov)

  Renesas R-Car PCIe controller driver:
   - Help the controller get to the L1 state since the hardware can't do
     it on its own (Marek Vasut)
   - Return PCI_ERROR_RESPONSE (~0) for reads that fail on PCIe (Marek
     Vasut)

  SiFive FU740 PCIe controller driver:
   - Drop redundant '-gpios' from DT GPIO lookup (Ben Dooks)
   - Force 2.5GT/s for initial device probe (Ben Dooks)

  Socionext UniPhier Pro5 controller driver:
   - Add NX1 DT binding and driver support (Kunihiko Hayashi)

  Synopsys DesignWare PCIe controller driver:
   - Restore MSI configuration so MSI works after resume (Jisheng
     Zhang)"

* tag 'pci-v5.18-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (94 commits)
  x86/PCI: Add #includes to asm/pci_x86.h
  PCI: ibmphp: Remove unused assignments
  PCI: cpqphp: Remove unused assignments
  PCI: fu740: Remove unused assignments
  PCI: kirin: Remove unused assignments
  PCI: Remove unused assignments
  PCI: Declare pci_filp_private only when HAVE_PCI_MMAP
  PCI: Avoid broken MSI on SB600 USB devices
  PCI: fu740: Force 2.5GT/s for initial device probe
  PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
  PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
  PCI: imx6: Assert i.MX8MM CLKREQ# even if no device present
  PCI: imx6: Invoke the PHY exit function after PHY power off
  PCI: rcar: Use PCI_SET_ERROR_RESPONSE after read which triggered an exception
  PCI: rcar: Finish transition to L1 state in rcar_pcie_config_access()
  PCI: dwc: Restore MSI Receiver mask during resume
  PCI: fu740: Drop redundant '-gpios' from DT GPIO lookup
  PCI/VGA: Replace full MIT license text with SPDX identifier
  PCI/VGA: Use unsigned format string to print lock counts
  PCI/VGA: Log bridge control messages when adding devices
  ...
2022-03-25 13:02:05 -07:00
Bjorn Helgaas
73c82469bd Merge branch 'pci/misc'
- Update the aer-inject URL (Yicong Yang)

- Declare pci_filp_private only when HAVE_PCI_MMAP to avoid unused struct
  definition (Krzysztof Wilczyński)

- Remove unused assignments (Bjorn Helgaas)

- Add #includes to asm/pci_x86.h to prevent build errors (Randy Dunlap)

* pci/misc:
  x86/PCI: Add #includes to asm/pci_x86.h
  PCI: ibmphp: Remove unused assignments
  PCI: cpqphp: Remove unused assignments
  PCI: fu740: Remove unused assignments
  PCI: kirin: Remove unused assignments
  PCI: Remove unused assignments
  PCI: Declare pci_filp_private only when HAVE_PCI_MMAP
  PCI/AER: Update aer-inject URL
2022-03-22 17:16:21 -05:00
Yicong Yang
602a4eda68 PCI/AER: Update aer-inject URL
The link to the aer-inject referenced leads to an empty repo and seems no
longer used. Replace it with the link mentioned in
Documentation/PCI/pcieaer-howto.rst.

Link: https://lore.kernel.org/r/20220115104921.21606-1-yangyicong@hisilicon.com
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2022-03-02 11:26:17 -06:00
Pali Rohár
904b10fb18 PCI: Add defines for normal and subtractive PCI bridges
Add these PCI class codes to pci_ids.h:

  PCI_CLASS_BRIDGE_PCI_NORMAL
  PCI_CLASS_BRIDGE_PCI_SUBTRACTIVE

Use these defines in all kernel code for describing PCI class codes for
normal and subtractive PCI bridges.

[bhelgaas: similar change in pci-mvebu.c]
Link: https://lore.kernel.org/r/20220214114109.26809-1-pali@kernel.org
Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2022-02-17 15:29:35 -06:00
Bjorn Helgaas
075b7d363c Revert "PCI/portdrv: Do not setup up IRQs if there are no users"
This reverts commit 0e8ae5a6ff.

0e8ae5a6ff ("PCI/portdrv: Do not setup up IRQs if there are no users")
reduced usage of IRQs when we don't think we need them.  But Joey, Sergiu,
and David reported choppy GUI rendering, systems that became unresponsive
every few seconds, incorrect values reported by cpufreq, and high IRQ 16
CPU usage.

Joey bisected the issues to 0e8ae5a6ff, so revert it until we figure out
a better solution.

Link: https://lore.kernel.org/r/20220210222717.GA658201@bhelgaas
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215533
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215546
Reported-by: Joey Corleone <joey.corleone@mail.ru>
Reported-by: Sergiu Deitsch <sergiu.deitsch@gmail.com>
Reported-by: David Spencer <dspencer577@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org	# v5.16+
Cc: Jan Kiszka <jan.kiszka@siemens.com>
2022-02-11 14:16:11 -06:00
Bjorn Helgaas
f5d3ca6fff Merge branch 'pci/errors'
- Add PCI_ERROR_RESPONSE and related definitions for signaling and checking
  for transaction errors on PCI (Naveen Naidu)

- Fabricate PCI_ERROR_RESPONSE data (~0) in config read wrappers, instead
  of in host controller drivers, when transactions fail on PCI (Naveen
  Naidu)

- Use PCI_POSSIBLE_ERROR() to check for possible failure of config reads
  (Naveen Naidu)

* pci/errors:
  PCI: xgene: Use PCI_ERROR_RESPONSE to identify config read errors
  PCI: hv: Use PCI_ERROR_RESPONSE to identify config read errors
  PCI: keystone: Use PCI_ERROR_RESPONSE to identify config read errors
  PCI: Use PCI_ERROR_RESPONSE to identify config read errors
  PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI/PME: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI/DPC: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI: pciehp: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI: vmd: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI/ERR: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI: rockchip-host: Drop error data fabrication when config read fails
  PCI: rcar-host: Drop error data fabrication when config read fails
  PCI: altera: Drop error data fabrication when config read fails
  PCI: mvebu: Drop error data fabrication when config read fails
  PCI: aardvark: Drop error data fabrication when config read fails
  PCI: kirin: Drop error data fabrication when config read fails
  PCI: histb: Drop error data fabrication when config read fails
  PCI: exynos: Drop error data fabrication when config read fails
  PCI: mediatek: Drop error data fabrication when config read fails
  PCI: iproc: Drop error data fabrication when config read fails
  PCI: thunder: Drop error data fabrication when config read fails
  PCI: Drop error data fabrication when config read fails
  PCI: Use PCI_SET_ERROR_RESPONSE() for disconnected devices
  PCI: Set error response data when config read fails
  PCI: Add PCI_ERROR_RESPONSE and related definitions
2022-01-13 09:57:52 -06:00
Bjorn Helgaas
fb6c45130a Merge branch 'pci/enumeration'
- Use pci_find_vsec_capability() instead of open-coding it (Andy
  Shevchenko)

- Convert pci_dev_present() stub from macro to static inline to avoid
  'unused variable' errors (Hans de Goede)

- Convert sysfs slot attributes from default_attrs to default_groups (Greg
  Kroah-Hartman)

- Use DWORD accesses for LTR, L1 SS to avoid BayHub OZ711LV2 erratum (Rajat
  Jain)

- Remove unnecessary initialization of static variables (Longji Guo)

* pci/enumeration:
  x86/PCI: Remove initialization of static variables to false
  PCI: Use DWORD accesses for LTR, L1 SS to avoid erratum
  PCI/sysfs: Use default_groups in kobj_type for slot attrs
  PCI: Convert pci_dev_present() stub to static inline
  PCI: Use pci_find_vsec_capability() when looking for TBT devices
2022-01-13 09:57:43 -06:00
Rajat Jain
4353594eb0 PCI: Use DWORD accesses for LTR, L1 SS to avoid erratum
Some devices have an erratum such that they only support DWORD accesses to
some registers.  E.g., this Bayhub O2 device ([VID:DID] = [0x1217:0x8621])
only supports DWORD accesses to LTR latency registers and L1 PM substates
control registers:

  https://github.com/rajatxjain/public_shared/blob/main/OZ711LV2_appnote.pdf

The L1 PM substate control registers are DWORD sized, and hence their
access in the kernel is already DWORD sized, so we don't need to do
anything for them.

However, the LTR registers being WORD sized, are in need of a solution.
Convert the WORD sized accesses to these registers into DWORD sized
accesses while saving and restoring them.

Link: https://lore.kernel.org/r/20211222012105.3438916-1-rajatja@google.com
Signed-off-by: Rajat Jain <rajatja@google.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2022-01-11 10:41:24 -06:00
Saheed O. Bolarinwa
fa285baf84 PCI/ASPM: Remove struct aspm_latency
The struct aspm_latency is now used only inside pcie_aspm_check_latency().

Replace struct aspm_latency variables with u32 variables and remove struct
aspm_latency.

Link: https://lore.kernel.org/r/20211119193732.12343-5-refactormyself@gmail.com
Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
2021-11-19 16:46:26 -06:00
Saheed O. Bolarinwa
6e332df7c3 PCI/ASPM: Stop caching device L0s, L1 acceptable exit latencies
Previously we calculated the device's acceptable L0s and L1 exit latencies
in pcie_aspm_cap_init() and cached them in struct pcie_link_state.

These values are only used in pcie_aspm_check_latency() where they are
compared with the actual exit latencies of the link.  This path is used
when removing or changing the D state of the device, so it's relatively low
frequency.

To reduce the amount of per-link data we store, remove the acceptable[]
arrays from struct pcie_link_state and calculate them directly from the
already-cached Device Capabilities register when needed.

[bhelgaas: use endpoint->devcap instead of reading it again]
Link: https://lore.kernel.org/r/20211119193732.12343-4-refactormyself@gmail.com
Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2021-11-19 16:46:21 -06:00
Saheed O. Bolarinwa
222578dad4 PCI/ASPM: Stop caching link L0s, L1 exit latencies
Previously we calculated the upstream and downstream L0s and L1 exit
latencies of the link in pcie_aspm_cap_init() and cached them in struct
pcie_link_state.latency_*.

These values are only used in pcie_aspm_check_latency() where they are
compared with the acceptable latencies on the link.  This path is used when
removing or changing the D state of the device, so it's relatively low
frequency.

To reduce the amount of per-link data we store, remove the latency_*
entries from struct pcie_link_state and calculate the latencies directly
where they are needed.

Link: https://lore.kernel.org/r/20211119193732.12343-3-refactormyself@gmail.com
Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2021-11-19 16:46:09 -06:00
Bolarinwa O. Saheed
43262f001b PCI/ASPM: Move pci_function_0() upward
Move pci_function_0() earlier so we can use it from other functions.

Link: https://lore.kernel.org/r/20211119193732.12343-2-refactormyself@gmail.com
Signed-off-by: Bolarinwa O. Saheed <refactormyself@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
2021-11-19 16:15:43 -06:00
Naveen Naidu
aa66ea10ba PCI/PME: Use PCI_POSSIBLE_ERROR() to check config reads
When config pci_ops.read() can detect failed PCI transactions, the data
returned to the CPU is PCI_ERROR_RESPONSE (~0 or 0xffffffff).

Obviously a successful PCI config read may *also* return that data if a
config register happens to contain ~0, so it doesn't definitively indicate
an error unless we know the register cannot contain ~0.

Use PCI_POSSIBLE_ERROR() to check the response we get when we read data
from hardware.  This unifies PCI error response checking and makes error
checks consistent and easier to find.

Compile tested only.

Link: https://lore.kernel.org/r/679ce049bccf10df3ca9ef4918ee2c3235afdaea.1637243717.git.naveennaidu479@gmail.com
Signed-off-by: Naveen Naidu <naveennaidu479@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2021-11-18 14:13:18 -06:00
Naveen Naidu
0242132da2 PCI/DPC: Use PCI_POSSIBLE_ERROR() to check config reads
When config pci_ops.read() can detect failed PCI transactions, the data
returned to the CPU is PCI_ERROR_RESPONSE (~0 or 0xffffffff).

Obviously a successful PCI config read may *also* return that data if a
config register happens to contain ~0, so it doesn't definitively indicate
an error unless we know the register cannot contain ~0.

Use PCI_POSSIBLE_ERROR() to check the response we get when we read data
from hardware.  This unifies PCI error response checking and makes error
checks consistent and easier to find.

Compile tested only.

Link: https://lore.kernel.org/r/9b0632f1f183432149f495cf12bdd5a72cc597a4.1637243717.git.naveennaidu479@gmail.com
Signed-off-by: Naveen Naidu <naveennaidu479@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2021-11-18 14:13:18 -06:00
Bjorn Helgaas
e0217c5ba1 Revert "PCI: Use to_pci_driver() instead of pci_dev->driver"
This reverts commit 2a4d9408c9.

Robert reported a NULL pointer dereference caused by the PCI core
(local_pci_probe()) calling the i2c_designware_pci driver's
.runtime_resume() method before the .probe() method.  i2c_dw_pci_resume()
depends on initialization done by i2c_dw_pci_probe().

Prior to 2a4d9408c9 ("PCI: Use to_pci_driver() instead of
pci_dev->driver"), pci_pm_runtime_resume() avoided calling the
.runtime_resume() method because pci_dev->driver had not been set yet.

2a4d9408c9 and b5f9c644eb ("PCI: Remove struct pci_dev->driver"),
removed pci_dev->driver, replacing it by device->driver, which *has* been
set by this time, so pci_pm_runtime_resume() called the .runtime_resume()
method when it previously had not.

Fixes: 2a4d9408c9 ("PCI: Use to_pci_driver() instead of pci_dev->driver")
Link: https://lore.kernel.org/linux-i2c/CAP145pgdrdiMAT7=-iB1DMgA7t_bMqTcJL4N0=6u8kNY3EU0dw@mail.gmail.com/
Reported-by: Robert Święcki <robert@swiecki.net>
Tested-by: Robert Święcki <robert@swiecki.net>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2021-11-11 13:36:22 -06:00
Bjorn Helgaas
78be29ab54 Merge branch 'pci/misc'
- Tidy setup-irq.c comments (Pranay Sanghai)

- Fix misspellings (Krzysztof Wilczyński)

- Fix sprintf(), sscanf() format mismatches (Krzysztof Wilczyński)

- Tidy cpqphp code formatting (Krzysztof Wilczyński)

- Remove unused pci_pool wrappers, which have been replaced by dma_pool
  (Cai Huoqing)

- Remove a redundant initialization in __pci_reset_function_locked() (Colin
  Ian King)

- Use 'unsigned int' instead of 'unsigned' (Krzysztof Wilczyński)

- Update PCI subsystem information in MAINTAINERS (Krzysztof Wilczyński)

- Include generic <linux/> headers instead of <asm/> for cpqphp and vmd
  (Krzysztof Wilczyński)

* pci/misc:
  PCI: vmd: Drop redundant includes of <asm/device.h>, <asm/msi.h>
  PCI: cpqphp: Use <linux/io.h> instead of <asm/io.h>
  MAINTAINERS: Update PCI subsystem information
  PCI: Prefer 'unsigned int' over bare 'unsigned'
  PCI: Remove redundant 'rc' initialization
  PCI: Remove unused pci_pool wrappers
  PCI: cpqphp: Format if-statement code block correctly
  PCI: Use unsigned to match sscanf("%x") in pci_dev_str_match_path()
  PCI: hv: Remove unnecessary use of %hx
  PCI: Correct misspelled and remove duplicated words
  PCI: Tidy comments
2021-11-05 11:28:47 -05:00
Bjorn Helgaas
ebf275b856 Merge branch 'pci/sysfs'
- Check for CAP_SYS_ADMIN before validating sysfs user input, not after
  (Krzysztof Wilczyński)

- Always return -EINVAL from sysfs "store" functions for invalid user input
  instead of -EINVAL sometimes and -ERANGE others (Krzysztof Wilczyński)

- Use kstrtobool() directly instead of the strtobool() wrapper (Krzysztof
  Wilczyński)

* pci/sysfs:
  PCI: Use kstrtobool() directly, sans strtobool() wrapper
  PCI/sysfs: Return -EINVAL consistently from "store" functions
  PCI/sysfs: Check CAP_SYS_ADMIN before parsing user input

# Conflicts:
#	drivers/pci/iov.c
2021-11-05 11:28:46 -05:00
Bjorn Helgaas
357cf0cddd Merge branch 'pci/portdrv'
- Don't setup portdrv IRQs if there are no port drivers that use them, to
  conserve vectors and avoid spurious events (Jan Kiszka)

* pci/portdrv:
  PCI/portdrv: Do not setup up IRQs if there are no users
2021-11-05 11:28:45 -05:00
Bjorn Helgaas
4917f7189b Merge branch 'pci/hotplug'
- Ignore Link Down/Up caused by error-induced Hot Reset so endpoint driver
  can remain bound to device during error recovery (Lukas Wunner)

- Remove unused resume err_handler (Lukas Wunner)

- Remove unused pcie_port_bus_{,un}register() declarations (Lukas Wunner)

- Skip compiling err.c when CONFIG_PCIEAER not set (Lukas Wunner)

* pci/hotplug:
  PCI/ERR: Reduce compile time for CONFIG_PCIEAER=n
  PCI/portdrv: Remove unused pcie_port_bus_{,un}register() declarations
  PCI/portdrv: Remove unused resume err_handler
  PCI: pciehp: Ignore Link Down/Up caused by error-induced Hot Reset
  PCI/portdrv: Rename pm_iter() to pcie_port_device_iter()
2021-11-05 11:28:43 -05:00
Uwe Kleine-König
2a4d9408c9 PCI: Use to_pci_driver() instead of pci_dev->driver
Struct pci_driver contains a struct device_driver, so for PCI devices, it's
easy to convert a device_driver * to a pci_driver * with to_pci_driver().
The device_driver * is in struct device, so we don't need to also keep
track of the pci_driver * in struct pci_dev.

Replace pci_dev->driver with to_pci_driver().  This is a step toward
removing pci_dev->driver.

[bhelgaas: split to separate patch]
Link: https://lore.kernel.org/r/20211004125935.2300113-11-u.kleine-koenig@pengutronix.de
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2021-10-18 09:20:15 -05:00
Lukas Wunner
f9a6c8ad49 PCI/ERR: Reduce compile time for CONFIG_PCIEAER=n
The sole non-static function in err.c, pcie_do_recovery(), is only
called from:

* aer.c (if CONFIG_PCIEAER=y)
* dpc.c (if CONFIG_PCIE_DPC=y, which depends on CONFIG_PCIEAER)
* edr.c (if CONFIG_PCIE_EDR=y, which depends on CONFIG_PCIE_DPC)

Thus, err.c need not be compiled if CONFIG_PCIEAER=n.

Also, pci_uevent_ers() and pcie_clear_device_status(), which are called
from err.c, can be #ifdef'ed away unless CONFIG_PCIEAER=y.

Since x86_64_defconfig doesn't enable CONFIG_PCIEAER, this change may
slightly reduce compile time for anyone doing a test build with that
config.

Link: https://lore.kernel.org/r/98f9041151268c1c035ab64cca320ad86803f64a.1627638184.git.lukas@wunner.de
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2021-10-16 09:16:59 -05:00
Lukas Wunner
bb6951b84f PCI/portdrv: Remove unused pcie_port_bus_{,un}register() declarations
Commit c6c889d932 ("PCI/portdrv: Remove pcie_port_bus_type link order
dependency") removed pcie_port_bus_{,un}register() but erroneously
retained their declarations in portdrv.h.  Remove them as well.

Link: https://lore.kernel.org/r/7fd76b0591c37287ab94d911d8fd9ab9a2afcd16.1627638184.git.lukas@wunner.de
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2021-10-15 14:25:18 -05:00
Lukas Wunner
80dcd36c38 PCI/portdrv: Remove unused resume err_handler
Commit 3e41a317ae ("PCI/AER: Remove unused aer_error_resume()")
removed the resume err_handler from AER.  Since no other port service
implements the callback, support for it can be removed from portdrv.
It can be revived later if need be, preferably by re-using the
pcie_port_device_iter() iterator.

Link: https://lore.kernel.org/r/25334149b604e005058aeb0fdf51e01f991d5d74.1627638184.git.lukas@wunner.de
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Keith Busch <kbusch@kernel.org>
2021-10-15 14:25:08 -05:00
Lukas Wunner
ea401499e9 PCI: pciehp: Ignore Link Down/Up caused by error-induced Hot Reset
Stuart Hayes reports that an error handled by DPC at a Root Port results
in pciehp gratuitously bringing down a subordinate hotplug port:

  RP -- UP -- DP -- UP -- DP (hotplug) -- EP

pciehp brings the slot down because the Link to the Endpoint goes down.
That is caused by a Hot Reset being propagated as a result of DPC.
Per PCIe Base Spec 5.0, section 6.6.1 "Conventional Reset":

  For a Switch, the following must cause a hot reset to be sent on all
  Downstream Ports: [...]

  * The Data Link Layer of the Upstream Port reporting DL_Down status.
    In Switches that support Link speeds greater than 5.0 GT/s, the
    Upstream Port must direct the LTSSM of each Downstream Port to the
    Hot Reset state, but not hold the LTSSMs in that state. This permits
    each Downstream Port to begin Link training immediately after its
    hot reset completes. This behavior is recommended for all Switches.

  * Receiving a hot reset on the Upstream Port.

Once DPC recovers, pcie_do_recovery() walks down the hierarchy and
invokes pcie_portdrv_slot_reset() to restore each port's config space.
At that point, a hotplug interrupt is signaled per PCIe Base Spec r5.0,
section 6.7.3.4 "Software Notification of Hot-Plug Events":

  If the Port is enabled for edge-triggered interrupt signaling using
  MSI or MSI-X, an interrupt message must be sent every time the logical
  AND of the following conditions transitions from FALSE to TRUE: [...]

  * The Hot-Plug Interrupt Enable bit in the Slot Control register is
    set to 1b.

  * At least one hot-plug event status bit in the Slot Status register
    and its associated enable bit in the Slot Control register are both
    set to 1b.

Prevent pciehp from gratuitously bringing down the slot by clearing the
error-induced Data Link Layer State Changed event before restoring
config space.  Afterwards, check whether the link has unexpectedly
failed to retrain and synthesize a DLLSC event if so.

Allow each pcie_port_service_driver (one of them being pciehp) to define
a slot_reset callback and re-use the existing pm_iter() function to
iterate over the callbacks.

Thereby, the Endpoint driver remains bound throughout error recovery and
may restore the device to working state.

Surprise removal during error recovery is detected through a Presence
Detect Changed event.  The hotplug port is expected to not signal that
event as a result of a Hot Reset.

The issue isn't DPC-specific, it also occurs when an error is handled by
AER through aer_root_reset().  So while the issue was noticed only now,
it's been around since 2006 when AER support was first introduced.

[bhelgaas: drop PCI_ERROR_RECOVERY Kconfig, split pm_iter() rename to
preparatory patch]
Link: https://lore.kernel.org/linux-pci/08c046b0-c9f2-3489-eeef-7e7aca435bb9@gmail.com/
Fixes: 6c2b374d74 ("PCI-Express AER implemetation: AER core and aerdriver")
Link: https://lore.kernel.org/r/251f4edcc04c14f873ff1c967bc686169cd07d2d.1627638184.git.lukas@wunner.de
Reported-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Tested-by: Stuart Hayes <stuart.w.hayes@gmail.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org # v2.6.19+: ba952824e6: PCI/portdrv: Report reset for frozen channel
Cc: Keith Busch <kbusch@kernel.org>
2021-10-15 14:23:46 -05:00