19 Aug, 2020

1 commit

  • [ Upstream commit 2a7e32d0547f41c5ce244f84cf5d6ca7fccee7eb ]

    The pci_cfg_wait queue is used to prevent user-space config accesses to
    devices while they are recovering from reset.

    Previously we used these operations on pci_cfg_wait:

    __add_wait_queue(&pci_cfg_wait, ...)
    __remove_wait_queue(&pci_cfg_wait, ...)
    wake_up_all(&pci_cfg_wait)

    The wake_up acquires the wait queue lock, but the add and remove do not.

    Originally these were all protected by the pci_lock, but cdcb33f98244
    ("PCI: Avoid possible deadlock on pci_lock and p->pi_lock"), moved
    wake_up_all() outside pci_lock, so it could race with add/remove
    operations, which caused occasional kernel panics, e.g., during vfio-pci
    hotplug/unplug testing:

    Unable to handle kernel read from unreadable memory at virtual address ffff802dac469000

    Resolve this by using wait_event() instead of __add_wait_queue() and
    __remove_wait_queue(). The wait queue lock is held by both wait_event()
    and wake_up_all(), so it provides mutual exclusion.

    Fixes: cdcb33f98244 ("PCI: Avoid possible deadlock on pci_lock and p->pi_lock")
    Link: https://lore.kernel.org/linux-pci/79827f2f-9b43-4411-1376-b9063b67aee3@huawei.com/T/#u
    Based-on: https://lore.kernel.org/linux-pci/20191210031527.40136-1-zhengxiang9@huawei.com/
    Based-on-patch-by: Xiang Zheng
    Signed-off-by: Bjorn Helgaas
    Tested-by: Xiang Zheng
    Cc: Heyi Guo
    Cc: Biaoxiang Ye
    Signed-off-by: Sasha Levin

    Bjorn Helgaas
     

07 Sep, 2019

1 commit


05 Oct, 2018

1 commit


05 Apr, 2018

1 commit

  • - consolidate VPD code in vpd.c (Bjorn Helgaas)

    * pci/vpd:
    PCI/VPD: Move VPD structures to vpd.c
    PCI/VPD: Move VPD quirks to vpd.c
    PCI/VPD: Move VPD sysfs code to vpd.c
    PCI/VPD: Move VPD access code to vpd.c

    Bjorn Helgaas
     

20 Mar, 2018

2 commits


02 Feb, 2018

1 commit

  • * pci/spdx:
    PCI: Add SPDX GPL-2.0+ to replace implicit GPL v2 or later statement
    PCI: Add SPDX GPL-2.0+ to replace GPL v2 or later boilerplate
    PCI: Add SPDX GPL-2.0 to replace COPYING boilerplate
    PCI: Add SPDX GPL-2.0 to replace GPL v2 boilerplate
    PCI: Add SPDX GPL-2.0 when no license was specified

    Bjorn Helgaas
     

27 Jan, 2018

1 commit

  • b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to
    files with no license") added SPDX GPL-2.0 to several PCI files that
    previously contained no license information.

    Add SPDX GPL-2.0 to all other PCI files that did not contain any license
    information and hence were under the default GPL version 2 license of the
    kernel.

    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Greg Kroah-Hartman

    Bjorn Helgaas
     

19 Jan, 2018

1 commit


29 Jun, 2017

1 commit

  • The generic PCI configuration space accessors are globally serialized via
    pci_lock. On larger systems this causes massive lock contention when the
    configuration space has to be accessed frequently. One such access pattern
    is the Intel Uncore performance counter unit.

    Provide a kernel config option which can be selected by an architecture
    when the low level PCI configuration space accessors in the architecture
    use their own serialization or can operate completely lockless.

    Signed-off-by: Thomas Gleixner
    Acked-by: Bjorn Helgaas
    Cc: Andi Kleen
    Cc: Peter Zijlstra
    Cc: Stephane Eranian
    Cc: Borislav Petkov
    Cc: linux-pci@vger.kernel.org
    Link: http://lkml.kernel.org/r/20170316215057.205961140@linutronix.de
    Signed-off-by: Thomas Gleixner

    Thomas Gleixner
     

27 May, 2017

1 commit

  • Callers normally treat the config space accessors as returning PCBIOS_*
    error codes, not Linux error codes (or they don't look at them at all). We
    have pcibios_err_to_errno() in case the error code needs to be translated.

    Fixes: 4b1038834739 ("PCI: Don't attempt config access to disconnected devices")
    Signed-off-by: Brian Norris
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Keith Busch

    Brian Norris
     

28 Apr, 2017

1 commit


19 Apr, 2017

1 commit

  • A PCI/PCI-X to PCI Express bridge, sometimes referred to as a "reverse
    bridge", is a bridge with conventional PCI or PCI-X on its primary side and
    a PCI Express Port on its secondary (downstream) side.

    That PCIe Port is a Downstream Port and could be connected to a slot, just
    like a Root Port or a Switch Downstream Port. Make pcie_downstream_port()
    return true for them, so we can access the Slot registers in the PCIe
    capability.

    Signed-off-by: Bjorn Helgaas

    Bjorn Helgaas
     

05 Apr, 2017

1 commit


30 Mar, 2017

2 commits

  • If we've detected the PCI device is disconnected, there is no need to
    attempt to access its config space since we know the operation will fail.
    Make all the config reads and writes return -ENODEV error immediately when
    in such a state.

    If a caller requests a config read to a disconnected device, return a data
    value of all 1's. This is the same as what hardware is expected to return
    when accessing a removed device, but software can do this faster without
    relying on hardware.

    Tested-by: Krishna Dhulipala
    Signed-off-by: Keith Busch
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Wei Zhang

    Keith Busch
     
  • Replace the inline PCI device config read and write accessors with exported
    functions. This is preparing for these functions to make use of private
    data.

    Tested-by: Krishna Dhulipala
    Signed-off-by: Keith Busch
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Wei Zhang

    Keith Busch
     

02 Mar, 2017

1 commit


16 Feb, 2017

1 commit


04 Feb, 2017

1 commit

  • The PCI core uses a fixed 50ms timeout when waiting for VPD accesses to
    complete. When an access does not complete within this period, a warning
    is logged and an error returned to the caller.

    While this default timeout is valid for most hardware, some devices can
    experience longer access delays under certain circumstances. For example,
    one of the IBM CXL Flash devices can take up to ~120ms in a worst-case
    scenario. These types of devices can benefit from an extended timeout.

    To support devices with a longer access delay, increase the timeout in
    pci_vpd_wait() to 125ms. The PCI specification is silent with respect to
    VPD delays, therefore there is no concern for violating a threshold.

    Tested-by: Uma Krishnan
    Signed-off-by: Matthew R. Ochs
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Gavin Shan

    Matthew R. Ochs
     

31 Jan, 2017

1 commit

  • pci_lock is an IRQ-safe spinlock that protects all accesses to PCI
    configuration space (see PCI_OP_READ() and PCI_OP_WRITE() in pci/access.c).

    The pci_cfg_access_unlock() path acquires pci_lock, then p->pi_lock (inside
    wake_up_all()). According to lockdep, there is a possible path involving
    snbep_uncore_pci_read_counter() that could acquire them in the reverse
    order: acquiring p->pi_lock, then pci_lock, which could result in a
    deadlock. Lockdep details are in the bugzilla below.

    Avoid the possible deadlock by dropping pci_lock before waking up any
    config access waiters.

    Link: https://bugzilla.kernel.org/show_bug.cgi?id=192901
    Signed-off-by: Bjorn Helgaas

    Bjorn Helgaas
     

22 Nov, 2016

1 commit

  • Hardware that supports only 32-bit config writes is not spec-compliant.
    For example, if software performs a 16-bit write, we must do a 32-bit read,
    merge in the 16 bits we intend to write, followed by a 32-bit write. If
    the 16 bits we *don't* intend to write happen to have any RW1C (write-one-
    to-clear) bits set, we just inadvertently cleared something we shouldn't
    have.

    Add a rate-limited warning when we do sub-32 bit config writes. Remove
    similar probe-time warnings from some of the affected host bridge drivers.

    Signed-off-by: Bjorn Helgaas
    Enthusiastically-Acked-by: Russell King
    Acked-by: Shawn Lin # rockchip
    Acked-by: Thierry Reding

    Bjorn Helgaas
     

16 Apr, 2016

1 commit

  • After 104daa71b396 ("PCI: Determine actual VPD size on first access"), the
    PCI core computes the valid VPD size by parsing the VPD starting at offset
    0x0. We don't attempt to read past that valid size because that causes
    some devices to crash.

    However, some devices do have data past that valid size. For example,
    Chelsio adapters contain two VPD structures, and the driver needs both of
    them.

    Add pci_set_vpd_size(). If a driver knows it is safe to read past the end
    of the VPD data structure at offset 0, it can use pci_set_vpd_size() to
    allow access to as much data as it needs.

    [bhelgaas: changelog, split patches, rename to pci_set_vpd_size() and
    return int (not ssize_t)]
    Fixes: 104daa71b396 ("PCI: Determine actual VPD size on first access")
    Tested-by: Steve Wise
    Signed-off-by: Casey Leedom
    Signed-off-by: Hariprasad Shenai
    Signed-off-by: Bjorn Helgaas

    Hariprasad Shenai
     

11 Mar, 2016

1 commit

  • Use usleep_range() instead of udelay() while waiting for a VPD access to
    complete. This is not a performance path, so no need to hog the CPU.

    Rationale for usleep_range() parameters:

    We clear PCI_VPD_ADDR_F for a read (or set it for a write), then wait for
    the device to change it. For a device that updates PCI_VPD_ADDR between
    our config write and subsequent config read, we won't sleep at all and
    can get the device's maximum rate.

    Sleeping a minimum of 10 usec per 4-byte access limits throughput to
    about 400Kbytes/second. VPD is small (32K bytes at most), and most
    devices use only a fraction of that.

    We back off exponentially up to 1024 usec per iteration. If we reach
    1024, we've already waited up to 1008 usec (16 + 32 + ... + 512), so if
    we miss an update and wait an extra 1024 usec, we can still get about
    1/2 of the device's maximum rate.

    Tested-by: Shane Seymour
    Tested-by: Babu Moger
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Hannes Reinecke

    Bjorn Helgaas
     

01 Mar, 2016

7 commits

  • We only support one flavor of VPD, so there's no need to complicate things
    by having a "generic" struct pci_vpd and a more specific struct
    pci_vpd_pci22.

    Fold struct pci_vpd_pci22 directly into struct pci_vpd.

    [bhelgaas: remove NULL check before kfree of dev->vpd (per kfreeaddr.cocci)]
    Tested-by: Shane Seymour
    Tested-by: Babu Moger
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Hannes Reinecke

    Bjorn Helgaas
     
  • There's only one kind of VPD, so we don't need to qualify it as "the
    version described by PCI spec rev 2.2."

    Rename the following symbols to remove unnecessary "pci22":

    PCI_VPD_PCI22_SIZE -> PCI_VPD_MAX_SIZE
    pci_vpd_pci22_size() -> pci_vpd_size()
    pci_vpd_pci22_wait() -> pci_vpd_wait()
    pci_vpd_pci22_read() -> pci_vpd_read()
    pci_vpd_pci22_write() -> pci_vpd_write()
    pci_vpd_pci22_ops -> pci_vpd_ops
    pci_vpd_pci22_init() -> pci_vpd_init()

    Tested-by: Shane Seymour
    Tested-by: Babu Moger
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Hannes Reinecke

    Bjorn Helgaas
     
  • The struct pci_vpd_ops.release function pointer is always
    pci_vpd_pci22_release(), so there's no need for the flexibility of a
    function pointer.

    Inline the pci_vpd_pci22_release() body into pci_vpd_release() and remove
    pci_vpd_pci22_release() and the struct pci_vpd_ops.release function
    pointer.

    Tested-by: Shane Seymour
    Tested-by: Babu Moger
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Hannes Reinecke

    Bjorn Helgaas
     
  • Move pci_vpd_release() so it's next to the other VPD functions. This puts
    it next to pci_vpd_pci22_init(), which allocates the space freed by
    pci_vpd_release().

    Tested-by: Shane Seymour
    Tested-by: Babu Moger
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Hannes Reinecke

    Bjorn Helgaas
     
  • pci_read_vpd() and pci_write_vpd() were stranded in the middle of config
    accessor functions. Move them close to the other VPD code in the file.
    No functional change.

    Tested-by: Shane Seymour
    Tested-by: Babu Moger
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Hannes Reinecke

    Bjorn Helgaas
     
  • PCI-2.2 VPD entries have a maximum size of 32k, but might actually be
    smaller than that. To figure out the actual size one has to read the VPD
    area until the 'end marker' is reached.

    Per spec, reading outside of the VPD space is "not allowed." In practice,
    it may cause simple read errors or even crash the card. To make matters
    worse not every PCI card implements this properly, leaving us with no 'end'
    marker or even completely invalid data.

    Try to determine the size of the VPD data when it's first accessed. If no
    valid data can be read an I/O error will be returned when reading or
    writing the sysfs attribute.

    As the amount of VPD data is unknown initially the size of the sysfs
    attribute will always be set to '0'.

    [bhelgaas: changelog, use 0/1 (not false/true) for bitfield, tweak
    pci_vpd_pci22_read() error checking]
    Tested-by: Shane Seymour
    Tested-by: Babu Moger
    Signed-off-by: Hannes Reinecke
    Signed-off-by: Bjorn Helgaas
    Cc: Alexander Duyck

    Hannes Reinecke
     
  • Make struct pci_vpd_pci22.busy a 1-bit field instead of a bool. We intend
    to add another flag, and two bitfields are cheaper than two bools.

    Tested-by: Shane Seymour
    Tested-by: Babu Moger
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Hannes Reinecke

    Bjorn Helgaas
     

09 Jan, 2016

1 commit

  • Fix all whitespace issues (missing or needed whitespace) in all files in
    drivers/pci. Code is compiled with allyesconfig before and after code
    changes and objects are recorded and checked with objdiff and they are not
    changed after this commit.

    Signed-off-by: Bogicevic Sasa
    Signed-off-by: Bjorn Helgaas

    Bogicevic Sasa
     

25 Sep, 2015

2 commits

  • 932c435caba8 ("PCI: Add dev_flags bit to access VPD through function 0")
    added PCI_DEV_FLAGS_VPD_REF_F0. Previously, we set the flag on every
    non-zero function of quirked devices. If a function turned out to be
    different from function 0, i.e., it had a different class, vendor ID, or
    device ID, the flag remained set but we didn't make VPD accessible at all.

    Flip this around so we only set PCI_DEV_FLAGS_VPD_REF_F0 for functions that
    are identical to function 0, and allow regular VPD access for any other
    functions.

    [bhelgaas: changelog, stable tag]
    Fixes: 932c435caba8 ("PCI: Add dev_flags bit to access VPD through function 0")
    Signed-off-by: Alex Williamson
    Signed-off-by: Bjorn Helgaas
    Acked-by: Myron Stowe
    Acked-by: Mark Rustad
    CC: stable@vger.kernel.org

    Alex Williamson
     
  • Commit 932c435caba8 ("PCI: Add dev_flags bit to access VPD through function
    0") passes PCI_SLOT(devfn) for the devfn parameter of pci_get_slot().
    Generally this works because we're fairly well guaranteed that a PCIe
    device is at slot address 0, but for the general case, including
    conventional PCI, it's incorrect. We need to get the slot and then convert
    it back into a devfn.

    Fixes: 932c435caba8 ("PCI: Add dev_flags bit to access VPD through function 0")
    Signed-off-by: Alex Williamson
    Signed-off-by: Bjorn Helgaas
    Acked-by: Myron Stowe
    Acked-by: Mark Rustad
    CC: stable@vger.kernel.org

    Alex Williamson
     

22 Jul, 2015

1 commit

  • Add a dev_flags bit, PCI_DEV_FLAGS_VPD_REF_F0, to access VPD through
    function 0 to provide VPD access on other functions. This is for hardware
    devices that provide copies of the same VPD capability registers in
    multiple functions. Because the kernel expects that each function has its
    own registers, both the locking and the state tracking are affected by VPD
    accesses to different functions.

    On such devices for example, if a VPD write is performed on function 0,
    *any* later attempt to read VPD from any other function of that device will
    hang. This has to do with how the kernel tracks the expected value of the
    F bit per function.

    Concurrent accesses to different functions of the same device can not only
    hang but also corrupt both read and write VPD data.

    When hangs occur, typically the error message:

    vpd r/w failed. This is likely a firmware bug on this device.

    will be seen.

    Never set this bit on function 0 or there will be an infinite recursion.

    Signed-off-by: Mark Rustad
    Signed-off-by: Bjorn Helgaas
    Acked-by: Alexander Duyck
    CC: stable@vger.kernel.org

    Mark Rustad
     

15 Jul, 2015

1 commit

  • As used in the PCIe spec, "Downstream Port" includes both Root Ports and
    Switch Downstream Ports. We sometimes checked for PCI_EXP_TYPE_DOWNSTREAM
    when we should have checked for PCI_EXP_TYPE_ROOT_PORT or
    PCI_EXP_TYPE_DOWNSTREAM.

    For a Root Port without a slot, the effect of this was that using
    pcie_capability_read_word() to read PCI_EXP_SLTSTA returned zero instead of
    showing the Presence Detect State bit hardwired to one as the PCIe Spec,
    r3.0, sec 7.8, requires. (This read is completed in software because
    previous PCIe spec versions didn't require PCI_EXP_SLTSTA to exist at all.)

    Nothing in the kernel currently depends on this (pciehp only reads
    PCI_EXP_SLTSTA on ports with slots), so this is a cleanup and not a
    functional change.

    Add a pcie_downstream_port() helper function and use it.

    Signed-off-by: Bjorn Helgaas
    Acked-by: Rafael J. Wysocki

    Bjorn Helgaas
     

23 Jan, 2015

1 commit

  • Many PCI controllers' configuration space accesses are memory-mapped and
    vary only in address calculation and access checks. There are 2 main
    access methods: a decoded address space such as ECAM or a single address
    and data register similar to x86. This implementation can support both
    cases as well as be used in cases that need additional pre- or post-access
    handling.

    Add a new pci_ops member, map_bus, which can do access checks and any
    necessary setup. It returns the address to use for the configuration space
    access. The access types supported are 32-bit only accesses or correct
    byte, word, or dword sized accesses.

    Tested-by: Thierry Reding
    Signed-off-by: Rob Herring
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Thierry Reding

    Rob Herring
     

14 Nov, 2014

1 commit

  • Previously we applied _HPX type 2 record Link Control register settings
    only to bridges with a subordinate bus. But it's better to apply them to
    all devices with a link because if the subordinate bus has not been
    allocated yet, we won't apply settings to the device.

    Use pcie_cap_has_lnkctl() to determine whether the device has a Link
    Control register instead of looking at dev->subordinate.

    [bhelgaas: changelog]
    Fixes: 6cd33649fa83 ("PCI: Add pci_configure_device() during enumeration")
    Signed-off-by: Yinghai Lu
    Signed-off-by: Bjorn Helgaas

    Yinghai Lu
     

11 Jun, 2014

1 commit

  • Merge quoted strings that are broken across lines into a single entity.
    The compiler merges them anyway, but checkpatch complains about it, and
    merging them makes it easier to grep for strings.

    No functional change.

    [bhelgaas: changelog, do the same for everything under drivers/pci]
    Signed-off-by: Ryan Desfosses
    Signed-off-by: Bjorn Helgaas

    Ryan Desfosses
     

28 May, 2014

1 commit

  • The PCI user-space config accessors pci_user_{read,write}_config_*() return
    negative error numbers, which were introduced by commit 34e3207205ef
    ("PCI: handle positive error codes"). That patch converted all positive
    error numbers from platform-specific PCI config accessors to -EINVAL, which
    means the callers don't know anything about the specific cause of the
    failure.

    The patch fixes the issue by converting the positive PCIBIOS_* error values
    to generic negative error numbers with pcibios_err_to_errno().

    [bhelgaas: changelog]
    Signed-off-by: Gavin Shan
    Signed-off-by: Bjorn Helgaas
    Acked-by: Greg Thelen

    Gavin Shan
     

14 Jan, 2014

1 commit

  • My philosophy is unused code is dead code. And dead code is subject to bit
    rot and is a likely source of bugs. Use it or lose it.

    This reverts db5679437a2b ("PCI: add interface to set visible size of
    VPD"), removing this interface:

    pci_vpd_truncate()

    [bhelgaas: split to separate patch, also remove prototype from pci.h]
    Signed-off-by: Stephen Hemminger
    Signed-off-by: Bjorn Helgaas

    Stephen Hemminger