- Require CAP_SYS_ADMIN to write to sysfs 'resourceN_resize' attributes
(Krzysztof Wilczyński)
- Convert PCI resource files to static attributes to avoid races that cause
'duplicate filename' warnings and boot panics (Krzysztof Wilczyński)
- Remove pci_create_sysfs_dev_files() and pci_remove_sysfs_dev_files(),
which are obsolete after converting to static attributes (Krzysztof
Wilczyński)
- Add security_locked_down(LOCKDOWN_PCI_ACCESS) to alpha PCI resource mmap
path to match the generic path (Krzysztof Wilczyński)
- Convert sysfs 'legacy_io' and 'legacy_mem' to static attributes
(Krzysztof Wilczyński)
- Remove pci_create_legacy_files() and pci_sysfs_init(), which are obsolete
after converting to static attributes (Krzysztof Wilczyński)
- Expose sysfs 'resourceN_resize' attributes only on platforms with PCI
mmap (Krzysztof Wilczyński)
- Use kstrtobool() to parse the 'rom' attribute input to avoid the
unexpected behavior of enabling the ROM when writing '0' with no trailing
newline (Krzysztof Wilczyński)
* pci/sysfs:
PCI/sysfs: Use kstrtobool() to parse the ROM attribute input
PCI/sysfs: Limit BAR resize attribute scope to platforms with PCI mmap
PCI/sysfs: Remove pci_create_legacy_files() and pci_sysfs_init()
PCI/sysfs: Convert legacy I/O and memory attributes to static definitions
PCI/sysfs: Add __weak pci_legacy_has_sparse() helper
alpha/PCI: Compute legacy size in pci_mmap_legacy_page_range()
PCI: Add macros for legacy I/O and memory address space sizes
PCI/sysfs: Remove pci_{create,remove}_sysfs_dev_files()
alpha/PCI: Convert resource files to static attributes
alpha/PCI: Add static PCI resource attribute macros
alpha/PCI: Remove WARN from __pci_mmap_fits() and __legacy_mmap_fits()
alpha/PCI: Fix __pci_mmap_fits() overflow for zero-length BARs
alpha/PCI: Use PCI resource accessor macros
alpha/PCI: Use BAR index in sysfs attr->private instead of resource pointer
alpha/PCI: Add security_locked_down() check to pci_mmap_resource()
PCI/sysfs: Limit pci_sysfs_init() late_initcall compile scope
PCI/sysfs: Add stubs for pci_{create,remove}_sysfs_dev_files()
PCI/sysfs: Warn about BAR resize failure in __resource_resize_store()
PCI/sysfs: Convert PCI resource files to static attributes
PCI/sysfs: Add static PCI resource attribute macros
PCI/sysfs: Add CAP_SYS_ADMIN check to __resource_resize_store()
PCI/sysfs: Split pci_llseek_resource() for device and legacy attributes
PCI/sysfs: Only allow supported resource types in I/O and MMIO helpers
PCI: Add pci_resource_is_io() and pci_resource_is_mem() helpers
PCI/sysfs: Use PCI resource accessor macros
- Check option ROM header signatures and lengths before accessing to avoid
page faults and alignment faults (Guixin Liu)
* pci/rom:
PCI: Check ROM header and data structure addr before accessing
PCI: Introduce named defines for PCI ROM
- Log device readiness timeouts as errors, not warnings (Bjorn Helgaas)
- Wait for device readiness after soft reset (D3hot -> D0uninitialized
transition), when the device may respond with Request Retry Status if it
needs more time to initialize (Bjorn Helgaas)
- Drop unnecessary retries when restoring BARs (Lukas Wunner)
* pci/reset:
PCI: Drop unnecessary retries when restoring BARs
PCI: Wait for device readiness after D3hot -> D0uninitialized transition
PCI: Log device readiness timeouts as errors
- Don't try to power on/off devices unless we know they actually support
power control (Manivannan Sadhasivam)
* pci/pwrctrl:
PCI/pwrctrl: Lock device when calling device_is_bound()
PCI/pwrctrl: Do not try to power on/off devices that don't need pwrctrl
PCI/pwrctrl: Move pci_pwrctrl_is_required() earlier in file
- Fix race between pci_proc_init() and pci_bus_add_device() (Krzysztof
Wilczyński)
* pci/procfs:
PCI/proc: Fix race between pci_proc_init() and pci_bus_add_device()
- Set power state to 'unknown' for all devices, not just those with
drivers, during suspend (Lukas Wunner)
- Skip restoring Resizable BARs and VF Resizable BARs if device doesn't
respond to config reads, to avoid invalid array accesses (Marco
Nenciarini)
- Add pci_suspend_retains_context() so drivers can tell whether devices may
be reset while resuming from suspend due to platform issues; use this in
nvme to avoid issues on Qcom RCs (Manivannan Sadhasivam)
* pci/pm:
nvme-pci: Use pci_suspend_retains_context() during suspend
PCI: qcom: Indicate broken L1SS exit during resume from system suspend
PCI: Indicate context lost if L1SS exit is broken during resume from system suspend
PCI: Add pci_suspend_retains_context() to check if device state is preserved during suspend
PCI/IOV: Skip VF Resizable BAR restore on read error
PCI: Skip Resizable BAR restore on read error
PCI: Stop setting cached power state to 'unknown' on unbind
- Prevent P2PDMA as well as CPU access to non-mappable BARs, e.g., s390 ISM
BARs (Matt Evans)
- Add Intel QAT, DSA, IAA devices to whitelist (Lukas Wunner)
* pci/p2pdma:
PCI/P2PDMA: Add Intel QAT, DSA, IAA devices to whitelist
PCI/P2PDMA: Avoid returning a provider for non_mappable_bars
- Remove MPS/MRRS Kconfig settings (CONFIG_PCIE_BUS_*) that worked around a
WiFi device defect (Bjorn Helgaas)
- Always lift 2.5GT/s restriction in PCIe failed link retraining to avoid
clamping a link to 2.5GT/s after hot-plug changes the device (Maciej W.
Rozycki)
- Don't bother trying to retrain a 2.5GT/s link at 2.5GT/s since nothing
would be gained by the retrain (Maciej W. Rozycki)
* pci/enumeration:
PCI: Bail out early for 2.5GT/s devices in PCIe failed link retraining
PCI: Use pcie_get_speed_cap() in PCIe failed link retraining
PCI: Always lift 2.5GT/s restriction in PCIe failed link retraining
PCI: Remove MPS/MRRS Kconfig settings (CONFIG_PCIE_BUS_*)
- Don't reconfigure ASPM when entering low-power state; only do it
when returning back to D0 (Carlos Bilbao)
* pci/aspm:
PCI/ASPM: Don't reconfigure ASPM entering low-power state
pci_write_rom() controls access to the ROM content through the
corresponding sysfs attribute, and treats the input as a request to
disable only when it matches the string "0\n" exactly:
if ((off == 0) && (*buf == '0') && (count == 2))
The count == 2 condition encodes the trailing newline that echo(1) appends.
This was found when userspace wrote "0" without a trailing newline aiming
to disable access, which failed to match the condition above and enabled
access instead. For example:
$ echo 0 > rom # "0\n", count 2, access disabled
$ echo -n 0 > rom # "0", count 1, access enabled
$ echo > rom # "", count 1, access enabled (likely not desirable)
Parse the input with kstrtobool(), which handles common boolean inputs such
as "0", "1", "n", "y" or "off", "on", with or without a trailing newline,
so both of the above disable access, and update the now stale comment.
As a side effect, input that does not parse as a boolean is rejected with
-EINVAL rather than enabling access. The documented "0" and "1" continue
to work as before, and rejecting malformed input brings the attribute in
line with how sysfs attributes typically handle it.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260612182448.552406-1-kwilczynski@kernel.org
Currently, __resource_resize_store() uses sysfs_remove_groups() and
sysfs_create_groups() on pci_dev_resource_attr_groups to tear down and
recreate the resourceN files after a BAR resize, so the updated BAR sizes
are visible in sysfs.
The resourceN files only exist on platforms that define HAVE_PCI_MMAP or
ARCH_GENERIC_PCI_MMAP_RESOURCE. On platforms that define neither,
pci_dev_resource_attr_groups is NULL and the sysfs_remove_groups() and
sysfs_create_groups() calls in __resource_resize_store() become no-ops.
Resizable BAR (ReBAR) is a PCI Express Extended Capability
(PCI_EXT_CAP_ID_REBAR) that requires PCIe extended config space. Every
PCIe-capable architecture defines HAVE_PCI_MMAP or
ARCH_GENERIC_PCI_MMAP_RESOURCE (via arch headers or the asm-generic/pci.h
fallback). Architectures without either only support conventional PCI and
cannot have any ReBAR-capable devices.
Move the resize show and store helpers, the per-BAR attribute definitions,
and the attribute group behind the existing #ifdef HAVE_PCI_MMAP ||
ARCH_GENERIC_PCI_MMAP_RESOURCE guard, and fold the group reference in
pci_dev_groups[] into the existing #if block.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-25-kwilczynski@kernel.org
Currently, pci_create_legacy_files() and pci_remove_legacy_files() are
no-op stubs. With legacy attributes now handled by static groups
registered via pcibus_groups[], no call site needs them.
Remove both functions, their declarations, and the call sites in
pci_register_host_bridge(), pci_alloc_child_bus(), and pci_remove_bus().
Remove the pci_sysfs_init() late_initcall and sysfs_initialized. The
late_initcall originally existed to create all the dynamic PCI sysfs files,
but with both resource and legacy attributes now handled by static groups,
it is no longer needed.
Remove the legacy_io and legacy_mem fields from struct pci_bus which were
used to track the dynamically allocated legacy attributes.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-24-kwilczynski@kernel.org
Currently, legacy_io and legacy_mem are dynamically allocated and created
by pci_create_legacy_files(), with pci_adjust_legacy_attr() updating the
attributes at runtime on Alpha to rename them and shift the size for sparse
addressing.
Convert to four static const attributes (legacy_io, legacy_io_sparse,
legacy_mem, legacy_mem_sparse) with .is_bin_visible() callbacks that use
pci_legacy_has_sparse() to select the appropriate variant per bus. The
sizes are compile-time constants and .size is set directly on each
attribute.
Register the groups in pcibus_groups[] under a HAVE_PCI_LEGACY guard so the
driver model handles creation and removal automatically.
Stub out pci_create_legacy_files() and pci_remove_legacy_files() as the
dynamic creation is no longer needed. Remove the __weak
pci_adjust_legacy_attr(), Alpha's override, and its declaration from both
Alpha and PowerPC asm/pci.h headers.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-23-kwilczynski@kernel.org
Currently, Alpha's sparse/dense legacy attribute handling is done via
pci_adjust_legacy_attr(), which updates dynamically allocated attributes at
runtime. The upcoming conversion to static attributes needs a way to
determine sparse support at visibility check time.
Add a __weak pci_legacy_has_sparse() that returns false by default. Alpha
overrides it to check has_sparse() on the bus host controller.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-22-kwilczynski@kernel.org
Currently, pci_mmap_legacy_page_range() reads the legacy resource size from
bus->legacy_mem->size or bus->legacy_io->size. This couples the mmap
bounds check to the struct pci_bus fields that will be removed when legacy
attributes are converted to static definitions.
Compute the size directly using PCI_LEGACY_MEM_SIZE (0x100000) and
PCI_LEGACY_IO_SIZE (0xffff) macros, and shift by 5 bits for sparse systems.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://patch.msgid.link/20260508043543.217179-21-kwilczynski@kernel.org
Add defines for the standard PCI legacy address space sizes, replacing the
raw literals used by the legacy sysfs attributes.
Then, replace open-coded values with the newly added macros.
No functional changes intended.
Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-20-kwilczynski@kernel.org
Currently, pci_create_sysfs_dev_files() and pci_remove_sysfs_dev_files()
are no-op stubs. With both the generic and Alpha resource files now
handled by static attribute groups, no platform needs dynamic per-device
sysfs file creation.
Remove both functions, their declarations, and the call sites in
pci_bus_add_device() and pci_stop_dev().
Remove __weak pci_create_resource_files() and pci_remove_resource_files()
stubs and their declarations in pci.h, as no architecture overrides them
anymore.
Remove the res_attr[] and res_attr_wc[] fields from struct pci_dev which
were used to track dynamically allocated resource attributes.
Finally, simplify pci_sysfs_init() to only handle legacy file creation
under HAVE_PCI_LEGACY, removing the per-device loop and the
HAVE_PCI_SYSFS_INIT helper added earlier.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-19-kwilczynski@kernel.org
Previously, Alpha's PCI resource files (resourceN, resourceN_sparse,
resourceN_dense) were dynamically created by pci_create_resource_files(),
which overrides the generic __weak implementation. The previous code
allocated bin_attributes at runtime and managed them via the res_attr[] and
res_attr_wc[] fields in struct pci_dev.
Convert to static const attributes with three attribute groups (plain,
sparse, dense), each with an .is_bin_visible() callback that checks
resource length, has_sparse(), and sparse_mem_mmap_fits(). A .bin_size()
callback provides the resource size to the kernfs node, with the sparse
variant shifting by 5 bits for byte-level addressing.
Register the groups via ARCH_PCI_DEV_GROUPS so the driver model handles
creation and removal automatically.
Use the new pci_resource_is_mem() helper for the type check, replacing the
open-coded bitwise flag test.
Finally, remove pci_create_resource_files(), pci_remove_resource_files(),
pci_create_attr(), and pci_create_one_attr() which are no longer needed.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://patch.msgid.link/20260508043543.217179-18-kwilczynski@kernel.org
Add macros for declaring static binary attributes for Alpha's PCI resource
files:
- pci_dev_resource_attr(), for dense/BWX systems (mmap dense)
- pci_dev_resource_sparse_attr(), for sparse systems (mmap sparse)
- pci_dev_resource_dense_attr(), for dense companion files (mmap dense)
Each macro creates a const bin_attribute with the BAR index stored in the
.private property and the appropriate .mmap() callback.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://patch.msgid.link/20260508043543.217179-17-kwilczynski@kernel.org
Remove the WARN() that fires when userspace attempts to mmap beyond the BAR
bounds. The check still returns 0 to reject the mapping, but the warning
is excessive for normal operation.
A similar warning was removed from the PCI core in the commit 3b519e4ea6
("PCI: fix size checks for mmap() on /proc/bus/pci files").
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
[bhelgaas: squash https://lore.kernel.org/all/20260508045824.GA3160093@rocinante]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://patch.msgid.link/20260508043543.217179-16-kwilczynski@kernel.org
Currently, __pci_mmap_fits() computes the BAR size using
"pci_resource_len() - 1", which wraps to a large value when the BAR length
is zero, causing the bounds check to incorrectly succeed.
Add an early return for empty resources.
Fixes: 10a0ef39fb ("PCI/alpha: pci sysfs resources")
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://patch.msgid.link/20260508043543.217179-15-kwilczynski@kernel.org
Replace direct pdev->resource[] accesses with pci_resource_n(), and
open-coded res->flags type checks with pci_resource_is_mem() and
pci_resource_start() helpers.
While at it, move the pci_resource_n() call directly into
pcibios_resource_to_bus() and drop the local struct resource pointer.
No functional changes intended.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://patch.msgid.link/20260508043543.217179-14-kwilczynski@kernel.org
Currently, Alpha's pci_create_one_attr() stores a resource pointer in
attr->private, and pci_mmap_resource() loops through all BARs to find
the matching index.
Store the BAR index directly in attr->private and retrieve the resource via
pci_resource_n(). This eliminates the loop and aligns with the convention
used by the generic PCI sysfs code.
The PCI core change was first added in the commit dca40b186b ("PCI: Use
BAR index in sysfs attr->private instead of resource pointer").
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://patch.msgid.link/20260508043543.217179-13-kwilczynski@kernel.org
Currently, Alpha's pci_mmap_resource() does not check
security_locked_down(LOCKDOWN_PCI_ACCESS) before allowing userspace to mmap
PCI BARs.
The generic version has had this check since commit eb627e1772 ("PCI:
Lock down BAR access when the kernel is locked down") to prevent DMA
attacks when the kernel is locked down.
Add the same check to Alpha's pci_mmap_resource().
Fixes: eb627e1772 ("PCI: Lock down BAR access when the kernel is locked down")
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://patch.msgid.link/20260508043543.217179-12-kwilczynski@kernel.org
Currently, pci_sysfs_init() and sysfs_initialized compile unconditionally,
even on platforms where static attribute groups handle all resource file
creation.
Place them behind a new HAVE_PCI_SYSFS_INIT macro, especially as the
late_initcall is only needed when:
- HAVE_PCI_LEGACY is set, to iterate buses and create legacy I/O and
memory files.
- Neither HAVE_PCI_MMAP nor ARCH_GENERIC_PCI_MMAP_RESOURCE is set, to
iterate devices and create resource files via the __weak
pci_create_resource_files() stub override (this is how the Alpha
architecture handles this currently).
On most systems both conditions are false and the entire late_initcall
compiles away.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-11-kwilczynski@kernel.org
On platforms with HAVE_PCI_MMAP or ARCH_GENERIC_PCI_MMAP_RESOURCE, resource
files are now handled by static attribute groups registered via
pci_dev_groups[].
Stub out the pci_create_sysfs_dev_files() and pci_remove_sysfs_dev_files(),
as the dynamic resource file creation is no longer needed.
Also, simplify pci_sysfs_init() on these platforms to only iterate buses
for legacy attributes creation, skipping the per-device loop.
Move the __weak stubs for pci_create_resource_files() and
pci_remove_resource_files() into the #else branch since only platforms
without HAVE_PCI_MMAP (such as Alpha architecture) still need them. Guard
the res_attr[] and res_attr_wc[] fields in struct pci_dev the same way.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-10-kwilczynski@kernel.org
Add a pci_warn() to __resource_resize_store(), so that BAR resize failures
are visible to the user, which can help troubleshoot any potential resource
resize issues.
While at it, rename the resource_resize_is_visible() to
resource_resize_attr_is_visible() along with the corresponding group
variable to align with the naming convention used by the resource attribute
groups.
Also, change the order of pci_dev_groups[] such that the resize group is
now located alongside the other resource groups.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-9-kwilczynski@kernel.org
Currently, the PCI resource files (resourceN, resourceN_wc) are dynamically
created by pci_create_sysfs_dev_files(), called from both
pci_bus_add_device() and the pci_sysfs_init() late_initcall, with only a
sysfs_initialized flag for synchronisation. This has caused warnings and
boot panics when both paths race on the same device, e.g.:
sysfs: cannot create duplicate filename '/devices/pci0000:3c/0000:3c:01.0/0000:3e:00.2/resource2'
This is especially likely on Devicetree-based platforms, where the PCI host
controllers are platform drivers that probe via the driver model, which can
happen during or after the late_initcall. As such, pci_bus_add_device()
and pci_sysfs_init() are more likely to overlap.
Convert to static const attributes with three attribute groups (I/O, UC,
WC), each with an .is_bin_visible() callback that checks resource flags,
BAR length, and non_mappable_bars. A .bin_size() callback provides
pci_resource_len() to the kernfs node for correct stat and lseek behaviour.
As part of this conversion:
- Rename pci_read_resource_io() and pci_write_resource_io() to
pci_read_resource() and pci_write_resource() since the callbacks are no
longer I/O-specific in the static attribute context.
- Update __resource_resize_store() to use sysfs_create_groups() and
sysfs_remove_groups(), which re-evaluates visibility and runs the
.bin_size() callback for the static resource attribute groups.
- Remove pci_create_resource_files(), pci_remove_resource_files(), and
pci_create_attr() which are no longer needed.
- Move the __weak stubs outside the #if guard so they remain available
for callers converted in subsequent commits.
Platforms that do not define the HAVE_PCI_MMAP macro or the
ARCH_GENERIC_PCI_MMAP_RESOURCE macro, such as Alpha architecture,
continue using their platform-specific resource file creation.
For reference, the dynamic creation dates back to the pre-Git era:
https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/drivers/pci/pci-sysfs.c?id=42298be0eeb5ae98453b3374c36161b05a46c5dc
The write-combine support was added in commit 45aec1ae72 ("x86: PAT
export resource_wc in pci sysfs").
Many other reports mentioned in the cover letter (first Link: below).
Link: https://lore.kernel.org/r/20260508043543.217179-1-kwilczynski@kernel.org/
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215515
Closes: https://github.com/openwrt/openwrt/issues/17143
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-8-kwilczynski@kernel.org
pci_proc_attach_device() creates procfs entries for PCI devices and is
called from pci_bus_add_device(). It lazily creates the per-bus procfs
directory (bus->procdir) via proc_mkdir() on first use, and returns early
if proc_initialized is not yet set.
On x86 with ACPI, PCI enumeration occurs at subsys_initcall, before
pci_proc_init() sets proc_initialized at device_initcall. The
for_each_pci_dev() loop in pci_proc_init() then creates procfs entries for
these already-enumerated devices, but runs without holding
pci_rescan_remove_lock.
On ARM64 with devicetree, PCI host bridges probe at device_initcall. With
async probing enabled, pci_bus_add_device() can run concurrently with
pci_proc_init(), and both may call pci_proc_attach_device() for the same
device or for different devices on the same bus. As pci_host_probe() holds
pci_rescan_remove_lock while pci_proc_init() does not, there is no
serialisation between the two paths.
When two threads concurrently call pci_proc_attach_device() for devices on
the same bus, both observe bus->procdir as NULL and both call proc_mkdir().
The proc filesystem serialises directory creation internally, so only one
caller succeeds. The other results in a warning like:
proc_dir_entry '000c:00/00.0' already registered
The caller receives NULL (duplicate entry) and unconditionally stores it to
bus->procdir, corrupting the valid pointer set by the first caller.
Serialise access to proc_initialized, proc_bus_pci_dir, bus->procdir and
dev->procent with a new mutex local to drivers/pci/proc.c, and store the
created entries to bus->procdir and dev->procent only on success, so a
failed creation can never overwrite a valid pointer.
Additionally, wrap the for_each_pci_dev() loop in pci_proc_init() with
pci_lock_rescan_remove() to serialise against concurrent PCI bus
operations, add an early return in pci_proc_attach_device() when
dev->procent is already set to make the function idempotent, and clear
bus->procdir in pci_proc_detach_bus() to prevent use of a dangling pointer
after proc_remove().
Reported-by: Shuan He <heshuan@bytedance.com>
Closes: https://lore.kernel.org/linux-pci/20250702155112.40124-2-heshuan@bytedance.com/
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://lore.kernel.org/r/20260611150543.511422-1-kwilczynski@kernel.org
pci_resource_alignment() calculates resource alignment and should not alter
its input structs. Make its input parameters const.
It requires making also pci_cardbus_resource_alignment() input const.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260429122617.7324-9-ilpo.jarvinen@linux.intel.com
pci_sriov_resource_alignment() inputs struct pci_dev which it should not
need to alter to calculate alignment.
Make pci_dev pci_sriov_resource_alignment() inputs const. It requires
making pci_iov_resource_size() input const as well.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260429122617.7324-8-ilpo.jarvinen@linux.intel.com
Convert input pci_dev for pseries_get_iov_fw_value() and pnv_iov_get() to
const to be able to convert pcibios_iov_resource_alignment() as well in an
upcoming change.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260429122617.7324-7-ilpo.jarvinen@linux.intel.com
__pci_bridge_assign_resources() inputs const pci_dev *bridge, but then
immediately casts const away to pass the bridge to
pdev_assign_resources_sorted().
As pdev_assign_resources_sorted() performs assignment of resources, it
is not possible to make its input parameter to const. Neither of the
__pci_bridge_assign_resources() callers requires the bridge parameter
to be const.
Thus, simply remove the out of place cast and convert the input parameter
to non-const.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260429122617.7324-5-ilpo.jarvinen@linux.intel.com
Callers of __pci_bridge_assign_resources() and __pci_bus_assign_resources()
perform WARN_ON_ONCE(list_empty(add_list))) checks to sanity check that all
optional sizes were processed (and removed) from the list. The empty list
sanity check is duplicated code so the more appropriate place for it would
be inside the called function.
Placing the empty list check into __pci_bus_assign_resources() also ensures
all callsites do perform the sanity check which currently is not the case
when being called from enable_slot(). This inconsistency was noted by
Sashiko though only inside its in depth log but not flagged as a real
problem, possibly because this is only a sanity check that should never
fire. Nonetheless, this sanity check has been very useful to catch problems
early in the past so it's good to do it consistently everywhere.
As __pci_bus_assign_resources() is a recursive function, it needs to be
renamed to __pci_bus_assign_resources_one() to only perform the empty list
check at the end of processing the entire hierarchy in
__pci_bus_assign_resources().
Suggested-by: sashiko.dev # Sanity check missing from enable_slot()
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260429122617.7324-4-ilpo.jarvinen@linux.intel.com
The resource fitting algorithm uses different names from the list holding
the optional sizes: added, add_head, add_list, and realloc_head. 'add_list'
sounds the most natural and some of the related variables also use 'add'
such as 'add_size'.
To reduce variation, rename 'added' and 'add_head' to 'add_list'. Also
rename some 'realloc_head' cases selectively to 'add_list'.
While it would be nice to rename every 'realloc_head' to 'add_list' for
consistency, it might create a backport headache with all the work going
into this algorithm that may need to be eventually backported. Thus, it's
better to leave 'realloc_head' as is for now.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260429122617.7324-3-ilpo.jarvinen@linux.intel.com
The first device on a PCI root bus determines whether the host bridge is
whitelisted for P2PDMA. All Intel Xeon chips since Ice Lake (ICX, 2021)
expose a device with ID 0x09a2 as first device. It is loosely associated
with the IOMMU. All these Xeon chips support P2PDMA, so since the addition
of the device with commit feaea1fe8b ("PCI/P2PDMA: Add Intel 3rd Gen
Intel Xeon Scalable Processors to whitelist"), P2PDMA has been allowed on
all new Xeons without the need to amend the whitelist:
Xeons with Performance Cores:
Sapphire Rapids (SPR, 2023)
Emerald Rapids (EMR, 2023)
Granite Rapids (GNR, 2024)
Diamond Rapids (DMR, 2026)
Xeons with Efficiency Cores:
Sierra Forest (SRF, 2024)
Clearwater Forest (CWF, 2026)
However these Xeons also expose accelerators as first device on a root bus
of its own:
QuickAssist Technology (QAT, crypto & compression accelerator)
Data Streaming Accelerator (DSA, dma engine)
In-Memory Analytics Accelerator (IAA, compression accelerator)
Whitelist them for P2PDMA as well. Move their Device ID macros from the
accelerator drivers to <linux/pci_ids.h> for reuse by P2PDMA code.
Unfortunately the Device IDs vary across Xeon generations as additional
features were added to the accelerators. This currently necessitates an
amendment for each new Xeon chip.
For future chips, this need shall be avoided by an ongoing effort to extend
ACPI HMAT with PCIe P2PDMA characteristics (latency, bandwidth, ordering
constraints). The PCI core will be able look up in this BIOS-provided ACPI
table whether P2PDMA is supported, instead of relying on a whitelist that
needs to be amended continuously.
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Acked-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com> # QAT
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/6aac4922b5fe7070b11874427a9285e42ddd05a4.1780585518.git.lukas@wunner.de
pci_suspend_retains_context() lets PCI client drivers know if the platform
can retain the device context during suspend. This is decided based on
several factors like:
- Firmware involvement at the end of suspend
- Any platform limitation in waking from low power state (e.g., L1SS)
This API may be extended in the future to cover other platform specific
issues impacting the device low power mode during system suspend.
Use this API instead of checks like pm_suspend_via_firmware(). When
pci_suspend_retains_context() returns false, assume the platform cannot
retain the context and shutdown the controller. If it returns true, assume
that the context will be retained and keep the device in low power mode.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260519-l1ss-fix-v2-4-b2c3a4bdeb15@oss.qualcomm.com
Qcom PCIe RCs can successfully exit from L1SS during OS runtime. However,
during system suspend, the Qcom PCIe RC driver may remove all resource
votes and turn off the PHY to maximize power savings.
Consequently, when the host is in system suspend with the link in L1SS and
the endpoint asserts CLKREQ#, the RC driver must restore the PHY and enable
the REFCLK. This recovery process causes the L1SS exit latency time to be
exceeded (roughly L10_REFCLK_ON + T_COMMONMODE). If the RC driver were to
retain all votes during suspend, L1SS exit would succeed without issue but
at the expense of higher power consumption.
When the host fails to move the link from L1SS to L0 within the
L10_REFCLK_ON + T_COMMONMODE time, the endpoint may treat it as a fatal
condition and trigger Link Down (LDn) during resume. This LDn results in a
reset that destroys the internal device state.
To ensure that the client drivers can properly handle this scenario, let
them know about this platform limitation by setting the
'pci_host_bridge::broken_l1ss_resume' flag.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260519-l1ss-fix-v2-3-b2c3a4bdeb15@oss.qualcomm.com
Per PCIe v7.0, sec 5.5.3.3.1, when exiting L1.2 due to an endpoint
asserting CLKREQ# signal, the REFCLK must be turned on within the latency
advertised in the LTR message. This requirement applies to L1.1 as well.
On some platforms like Qcom, these requirements are satisfied during OS
runtime, but not while resuming from the system suspend. This happens
because the PCIe RC driver may remove all resource votes and turn off the
PHY analog circuitry during suspend to maximize power savings while keeping
the link in L1SS.
Consequently, when the endpoint asserts CLKREQ# to wake up, the RC driver
must restore the PHY and enable the REFCLK. When this recovery process
exceeds the L1SS exit latency time (roughly L10_REFCLK_ON + T_COMMONMODE),
the endpoint may treat it as a fatal condition and trigger Link Down (LDn).
This results in a reset that destroys the internal device state.
So to indicate this platform limitation to the client drivers, introduce a
new flag 'pci_host_bridge::broken_l1ss_resume' and check it in
pci_suspend_retains_context(). If the flag is set by the RC driver, the API
will return 'false' indicating the client drivers that the device context
may not be retained and the drivers must be prepared for context loss.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260519-l1ss-fix-v2-2-b2c3a4bdeb15@oss.qualcomm.com
Currently, PCI endpoint drivers (e.g. nvme) use pm_suspend_via_firmware()
to check whether device state is preserved during system suspend. If
firmware will be invoked at the end of suspend, we don't know whether
devices will retain their internal state.
But device context might be lost due to platform issues as well. Having
those checks in endpoint drivers will not scale and will cause a lot of
code duplication.
Add pci_suspend_retains_context() as a sole point of truth that the
endpoint drivers can rely on to check whether they can expect the device
context to be retained or not.
If pci_suspend_retains_context() returns 'false', drivers need to prepare
for context loss by performing actions such as resetting the device, saving
the context, shutting it down etc. If it returns 'true', drivers do not
need to perform any special action and can leave the device in active
state.
Right now, this API only incorporates pm_suspend_via_firmware(), but will
be extended in future commits.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260519-l1ss-fix-v2-1-b2c3a4bdeb15@oss.qualcomm.com
The kerneldoc for device_is_bound() states that it must be called with
the device lock taken. Synchronize the two calls in pwrctrl core.
Fixes: b35cf3b6aa ("PCI/pwrctrl: Add APIs to power on/off pwrctrl devices")
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/20260518100700.47581-1-bartosz.golaszewski@oss.qualcomm.com
In 2012, commit 26f41062f2 ("PCI: check for pci bar restore completion
and retry") amended pci_restore_state() to attempt BAR restoration up to 10
times. This was necessary because back in the day, only a 100 msec delay
was observed after pcie_flr() carried out a Function Level Reset. The
retries ensured that BARs were restored even if devices needed more time to
come out of reset.
In 2016, commit 5adecf817d ("PCI: Wait for up to 1000ms after FLR reset")
extended the delay to 1 sec. Commit a2758b6b8f ("PCI: Rename
pci_flr_wait() to pci_dev_wait() and make it generic") subsequently
extended it further to 60 sec.
The lengthened delay makes it unnecessary to retry BAR restoration, so
drop it.
Reported-by: Bjorn Helgaas <bhelgaas@google.com>
Closes: https://lore.kernel.org/r/20260416225745.GA41850@bhelgaas/
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/785c98b50a7a00d0698848c75d51b8f5669ad18f.1777814679.git.lukas@wunner.de
For a device that advertises No_Soft_Reset == 0, a transition from D3hot to
D0uninitialized is a soft reset, and the resulting internal device state is
undefined.
Per PCIe r7.0, sec 2.3.1, a transition from D3hot to D0uninitialized
mandates a minimum 10 ms delay before accessing the device. Following this
delay, the device is permitted to respond to initial configuration requests
with a Request Retry Status (RRS) completion status if it needs more time
to initialize.
Call pci_dev_wait() after pci_power_up() performs a D3hot->D0uninitialized
transition to ensure the device is ready to accept config accesses, as is
done after the similar transition in pci_pm_reset().
If the device is already ready, this is essentially a no-op except for one
additional config read.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Link: https://patch.msgid.link/20260518191220.636213-3-bhelgaas@google.com
pci_dev_wait() waits for a device to be Configuration-Ready after a reset,
such as a Function-Level Reset (FLR), a soft reset during a D3hot->
D0uninitialized transition when No_Soft_Reset == 0), or a power-up sequence
from D3cold->D0uninitialized.
If pci_dev_wait() returns success, the device is guaranteed to respond to
configuration requests with Successful Completion status. If it times out,
device is completely non-responsive.
Upgrade the log level from pci_warn() to pci_err() to reflect this failure
state.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Link: https://patch.msgid.link/20260518191220.636213-2-bhelgaas@google.com
Add three macros for declaring static binary attributes for PCI resource
files:
- pci_dev_resource_io_attr(), for I/O BAR resources (read/write)
- pci_dev_resource_uc_attr(), for memory BAR resources (mmap uncached)
- pci_dev_resource_wc_attr(), for write-combine resources (mmap WC)
Each macro only sets the callbacks its resource type needs. The I/O macro
conditionally includes mmap support via __PCI_RESOURCE_IO_MMAP_ATTRS on
architectures where arch_can_pci_mmap_io() is true at compile time (such as
PowerPC, SPARC, and Xtensa).
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-7-kwilczynski@kernel.org
Currently, the __resource_resize_store() allows writing to the
resourceN_resize sysfs attribute to change a BAR's size without checking
for capabilities, currently relying only on the file access check.
Resizing a BAR modifies PCI device configuration and can disrupt active
drivers. After the upcoming conversion to static attributes, it will also
trigger resource file updates via sysfs_update_groups().
Add a CAP_SYS_ADMIN check to prevent unprivileged users from performing BAR
resize operations.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://patch.msgid.link/20260508043543.217179-6-kwilczynski@kernel.org
Both legacy and resource attributes set .f_mapping = iomem_get_mapping, so
the default generic_file_llseek() would consult iomem_inode for the file
size, which knows nothing about the attribute. That is why custom llseek
callbacks exist.
Currently, the legacy and resource attributes have .size set at creation
time, as such, using the attr->size is sufficient. However, the upcoming
static resource attributes will have .size == 0 set, since they are const,
and the .bin_size() callback will be used to provide the real size to
kernfs instead.
The legacy attributes operate on a struct pci_bus, not struct pci_dev, so
calling to_pci_dev() on them would be invalid.
Thus, split pci_llseek_resource() into two functions:
- pci_llseek_resource(), which derives the file size from the BAR using
pci_resource_len().
- pci_llseek_resource_legacy(), which uses attr->size directly.
Update the dynamic legacy attribute creation to use the new
pci_llseek_resource_legacy() callback.
The original pci_llseek_resource() was added in commit 24de09c16f ("PCI:
Implement custom llseek for sysfs resource entries").
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://patch.msgid.link/20260508043543.217179-5-kwilczynski@kernel.org