0516c8bcd2 ("PCI: PCIe portdrv: Simplily probe callback of service
drivers") removed the "id" argument of aer_probe() but neglected to remove
the kernel-doc comment. Update the comment.
[bhelgaas: changelog]
Signed-off-by: Cao jin <caoj.fnst@cn.fujitsu.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Save the position of the error reporting capability so it doesn't need to
be rediscovered during error handling.
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Lukas Wunner <lukas@wunner.de>
When handling AER events, we previously allocated a struct aer_err_info,
processed the error, and freed the struct. But aer_isr_one_error() is
serialized by rpc_mutex, so we never need more than one copy of the struct,
and the struct is only about 70 bytes, so we're not saving much by
allocating it dynamically.
Embed a struct aer_err_info directly in struct aer_rpc, which is allocated
at probe-time by aer_probe().
[bhelgaas: changelog]
Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Currently the AER severity is being translated twice in the code flow for
PCIe errors. It is first translated in ghes_do_proc() before calling into
the AER driver. Then it is translated again when the AER driver calls
cper_print_aer(). This causes the severity that is used in
cper_print_aer() to be incorrect.
Remove the second translation that is in cper_print_aer() since this
function is already receiving the correct AER severity.
Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Borislav Petkov <bp@suse.de>
Per the PCI Firmware spec, r3.0, sec 4.5.1, on ACPI systems, the OS must
not use AER unless _OSC is present and _OSC grants AER control to the OS.
The aerdriver.forceload kernel parameter was a way to enable Linux AER
support on ACPI systems that lack _OSC or fail to grant control the the OS.
Enabling Linux AER support when the firmware doesn't want us to is a recipe
for problems, e.g., the firmware might be handling AER itself.
Remove the aerdriver.forceload kernel parameter and related supporting
code.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
The aerdriver.nosourceid kernel parameter was intended for working around
broken chipsets don't supply the source ID for AER events. We recently
added PCI_BUS_FLAGS_NO_AERSID, which can be set by quirks for the same
purpose.
Remove the aerdriver.nosourceid kernel parameter. For anything other than
debugging, asking users to find and use kernel parameters is a poor user
experience. Instead, we should add PCI_BUS_FLAGS_NO_AERSID quirks for any
hardware that needs it.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Allow root port buses to choose to skip source id matching when finding the
faulting device. Certain root port devices may return an incorrect source
ID and recommend to scan child device registers for AER notifications.
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
* pci/ptm:
PCI: Add PTM clock granularity information
PCI: Add pci_enable_ptm() for drivers to enable PTM on endpoints
PCI: Add Precision Time Measurement (PTM) support
The PTM Control register (PCIe r3.1, sec 7.32.3) contains an Effective
Granularity field:
This provides information relating to the expected accuracy of the PTM
clock, but does not otherwise affect the PTM mechanism.
Set the Effective Granularity based on the PTM Root and any intervening PTM
Time Sources.
This does not set Effective Granularity for Root Complex Integrated
Endpoints because I don't know how to figure out clock granularity for
them. The spec says:
... system software must set [Effective Granularity] to the value
reported in the Local Clock Granularity field by the associated PTM
Time Source.
but I don't know how to identify the associated PTM Time Source. Normally
it's the upstream bridge, but an integrated endpoint has no upstream
bridge.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This code is not being built as a module by anyone:
obj-$(CONFIG_PCIEAER) += aerdriver.o
aerdriver-objs := aerdrv_errprint.o aerdrv_core.o aerdrv.o
drivers/pci/pcie/aer/Kconfig:config PCIEAER
drivers/pci/pcie/aer/Kconfig: bool "Root Port Advanced Error Reporting support"
Remove uses of MODULE_DESCRIPTION(), MODULE_AUTHOR(), MODULE_LICENSE(),
etc., so that when reading the driver there is no doubt it is builtin-only.
The information is preserved in comments at the top of the file.
Note that for non-modular code, module_init() translates to
device_initcall().
[bhelgaas: changelog]
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Tom Long Nguyen <tom.l.nguyen@intel.com>
This code is not being built as a module by anyone:
config PCIE_PME
def_bool y
depends on PCIEPORTBUS && PM
Remove traces of modularity so that when reading the driver there is no
doubt it is builtin-only.
Also delete the .remove function, since that doesn't seem to have a
sensible use case. With "normal" endpoint drivers, we have in the past set
the suppress_bind_attrs bit to make it clear that the use of ".remove" in a
builtin driver was deleted, but here for PCI, it seems overkill to jump
through the pcie_port_service_driver and into the struct device_driver in
order to finally try and do something similar with the bind setting.
Note that for non-modular code, module_init() translates to
device_initcall().
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This code is not being built as a module by anyone:
drivers/pci/pcie/Kconfig:config PCIE_DPC
drivers/pci/pcie/Kconfig: bool "PCIe Downstream Port Containment support"
Remove uses of MODULE_DESCRIPTION(), MODULE_AUTHOR(), MODULE_LICENSE(),
etc., so that when reading the driver there is no doubt it is builtin-only.
The information is preserved in comments at the top of the file.
Note that for non-modular code, module_init() translates to
device_initcall().
[bhelgaas: changelog]
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Keith Busch <keith.busch@intel.com>
CC: Mika Westerberg <mika.westerberg@linux.intel.com>
This code is not being built as a module by anyone:
pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
drivers/pci/pcie/Kconfig:config PCIEPORTBUS
drivers/pci/pcie/Kconfig: bool "PCI Express Port Bus support"
Remove uses of MODULE_DESCRIPTION(), MODULE_AUTHOR(), MODULE_LICENSE(),
etc., so that when reading the driver there is no doubt it is builtin-only.
The information is preserved in comments at the top of the file.
Note that for non-modular code, MODULE_DEVICE_TABLE is a no-op and
module_init() translates to device_initcall().
[bhelgaas: changelog, remove unused DRIVER_* macros]
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Tom Long Nguyen <tom.l.nguyen@intel.com>
Add an pci_enable_ptm() interface so drivers can enable PTM.
The PCI core enables PTM on PTM Roots and switches automatically, but we
don't enable PTM on endpoints unless a driver requests it.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Add Precision Time Measurement (PTM) support (see PCIe r3.1, sec 6.22).
Enable PTM on PTM Root devices and switch ports. This does not enable PTM
on endpoints.
There currently are no PTM-capable devices on the market, but it is
expected to be supported by the Intel Apollo Lake platform.
[bhelgaas: complete rework]
Signed-off-by: Jonathan Yong <jonathan.yong@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
* pci/aspm:
PCI/ASPM: Remove redundant check of pcie_set_clkpm
* pci/dpc:
PCI: Remove DPC tristate module option
PCI: Bind DPC to Root Ports as well as Downstream Ports
PCI: Fix whitespace in struct dpc_dev
PCI: Convert Downstream Port Containment driver to use devm_* functions
* pci/hotplug:
PCI: Allow additional bus numbers for hotplug bridges
* pci/misc:
PCI: Include <asm/dma.h> for isa_dma_bridge_buggy
PCI: Make bus_attr_resource_alignment static
MAINTAINERS: Add file patterns for PCI device tree bindings
PCI: Fix comment typo
* pci/msi:
PCI/MSI: irqchip: Fix PCI_MSI dependencies
* pci/pm:
PCI: pciehp: Ignore interrupts during D3cold
PCI: Document connection between pci_power_t and hardware PM capability
PCI: Add runtime PM support for PCIe ports
ACPI / hotplug / PCI: Runtime resume bridge before rescan
PCI: Power on bridges before scanning new devices
PCI: Put PCIe ports into D3 during suspend
PCI: Don't clear d3cold_allowed for PCIe ports
PCI / PM: Enforce type casting for pci_power_t
* pci/virtualization:
PCI: Add ACS quirk for Solarflare SFC9220
PCI: Add DMA alias quirk for Adaptec 3805
PCI: Mark Atheros AR9485 and QCA9882 to avoid bus reset
PCI: Add function 1 DMA alias quirk for Marvell 88SE9182
Change the Downstream Port Containment config type from tristate to bool.
The driver doesn't automatically load based on any rules, so it needs to be
built-in in order to bind to devices it needs to drive.
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
PCIe port type values are not flags, so OR'ing them is not correct.
Previously the result was equivalent to PCIe Downstream Ports, so we were
missing binding to DPC-capable Root Ports.
Change the type to 'any' so we can bind to both port types. While this
will cause the code to check Upstream Ports, the driver won't claim them
since they are not DPC-capable.
Reported-by: Alexander Antonov <alexanderx.v.antonov@intel.com>
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Mika Westerberg <mika.westerberg@linux.intel.com>
Use the device resource management (devm) interfaces so we don't need to
explicitly release resources on failure paths or when the driver is
removed.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Keith Busch <keith.busch@intel.com>
Add back runtime PM support for PCIe ports that was removed by
fe9a743a26 ("PCI/PM: Drop unused runtime PM support code for PCIe
ports").
We cannot enable it automatically for all ports since there have been
problems previously [1]. In summary suspended PCIe ports were not able
to deal with ACPI-based hotplug reliably. One reason why this might happen
is the fact that when a PCIe port is powered down, config space access to
the devices behind the port is not possible. If the BIOS hotplug SMI
handler assumes the port is always in D0 it will not be able to find the
hotplugged devices. To be on the safe side only enable runtime PM if the
port does not claim to support hotplug.
For PCIe ports not using hotplug, we enable and allow runtime PM
automatically. Since 'bridge_d3' can be changed any time we check this in
driver ->runtime_idle() and ->runtime_suspend() and only allow runtime
suspend if the flag is still set. Use autosuspend with default of 100ms
idle time to prevent the port from repeatedly suspending and resuming on
continuous configuration space access of devices behind the port.
The actual power transition to D3 and back is handled in the PCI core.
Idea to automatically unblock (allow) runtime PM for PCIe ports came from
Dave Airlie.
[1] https://bugzilla.kernel.org/show_bug.cgi?id=53811
This includes a fix for lockdep issue reported by Valdis Kletnieks.
Tested-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The PCI core skips bridges and ports when the system is suspended. The PCI
core checks return value of pci_has_subordinate() in pci_pm_suspend_noirq()
to skip all devices where it is non-zero (which means PCI bridges and PCIe
ports).
Since PCIe ports are never suspended in the first place, there is no need
to set d3cold_allowed for them.
Tested-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Without supporting clock PM capable, if we want to disable clkpm, we don't
need this extra check as it must already be zero for the enable argument.
And it's the same for enabling clkpm here. So let's remove this check.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
* pci/hotplug:
PCI: Use cached copy of PCI_EXP_SLTCAP_HPC bit
* pci/resource:
PCI: Disable all BAR sizing for devices with non-compliant BARs
x86/PCI: Mark Broadwell-EP Home Agent 1 as having non-compliant BARs
PCI: Identify Enhanced Allocation (EA) BAR Equivalent resources in sysfs
We cache the PCI_EXP_SLTCAP_HPC bit in pci_dev->is_hotplug_bridge on device
probe, so there's no need to read it again on allocation of port service
devices.
No functional change intended.
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
* pci/dpc:
PCI: Add Downstream Port Containment driver
PCI: Add Downstream Port Containment portdrv service type
PCI: Widen portdrv service type from 4 bits to 8 bits
* pci/resource:
alpha/PCI: Call iomem_is_exclusive() for IORESOURCE_MEM, but not IORESOURCE_IO
PCI: Supply CPU physical address (not bus address) to iomem_is_exclusive()
* pci/thunderbolt:
thunderbolt: Fix double free of drom buffer
Add driver for the PCI Express Downstream Port Containment extended
capability. DPC is an optional capability to contain uncorrectable errors
below a port.
For more information on DPC, please see PCI Express Base Specification
Revision 4, section 7.31, or view the PCI-SIG DPC ECN here:
https://pcisig.com/sites/default/files/specification_documents/ECN_DPC_2012-02-09_finalized.pdf
When a DPC event is triggered, the hardware disables downstream links, so
the DPC driver schedules removal for all devices below this port. This may
happen concurrently with a PCIe hotplug driver if enabled. When all
downstream devices are removed and the link state transitions to disabled,
the DPC driver clears the DPC status and interrupt bits so the link may
retrain for a newly connected device.
[bhelgaas: clear (not set) DPC_CTL bits on remove, whitespace cleanup]
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Lukas Wunner <lukas@wunner.de>
Add the Downstream Port Containment (PCIE_PORT_SERVICE_DPC) portdrv service
type, available if the device has the DPC extended capability.
[bhelgaas: split to separate patch, changelog]
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
The names of port service devices previously used one nibble to encode the
port type and another nibble to encode the service type. We're about to
add a fifth service type, so change device names to use one *byte* to
encode the service type.
For example, a hotplug port service on a downstream bridge was previously
called "pcie24" and is now called "pcie204". The "2" encodes the device
type (PCI_EXP_TYPE_DOWNSTREAM - 4), and the "4" (now "04") encodes the
service (PCIE_PORT_SERVICE_HP).
Based on Lukas Wunner's patch:
b688d6e487
[bhelgaas: split to separate patch, expand changelog]
Based-on-patch-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Now that pcie_port_acpi_setup() always returns 0, make it and its callers
void functions and stop checking the return values.
[bhelgaas: changelog]
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Host bridges we discover via ACPI, i.e., PNP0A03 and PNP0A08 devices, may
have an _OSC method by which the OS can ask the platform for control of
PCIe features like native hotplug, power management events, AER, etc.
Previously, if we found a bridge without an ACPI device, we assumed we did
not have permission to use any of these PCIe features. That seems
unreasonably restrictive.
If we find no ACPI device, assume we can take control of all PCIe features.
The Intel Volume Management Device (VMD) is one such bridge with no ACPI
device. Prior to this change, users had to boot with "pcie_ports=native"
to get hotplug and other services to work below the VMD Root Port.
[bhelgaas: changelog]
Suggested-by: Bjorn Helgaas <helgaas@kernel.org>
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
* pci/aer:
PCI/AER: Log aer_inject error injections
PCI/AER: Log actual error causes in aer_inject
PCI/AER: Use dev_warn() in aer_inject
PCI/AER: Fix aer_inject error codes
* pci/enumeration:
PCI: Fix broken URL for Dell biosdevname
* pci/kconfig:
PCI: Cleanup pci/pcie/Kconfig whitespace
PCI: Include pci/hotplug Kconfig directly from pci/Kconfig
PCI: Include pci/pcie/Kconfig directly from pci/Kconfig
* pci/misc:
PCI: Add PCI_CLASS_SERIAL_USB_DEVICE definition
PCI: Add QEMU top-level IDs for (sub)vendor & device
unicore32: Remove unused HAVE_ARCH_PCI_SET_DMA_MASK definition
PCI: Consolidate PCI DMA constants and interfaces in linux/pci-dma-compat.h
PCI: Move pci_dma_* helpers to common code
frv/PCI: Remove stray pci_{alloc,free}_consistent() declaration
* pci/virtualization:
PCI: Wait for up to 1000ms after FLR reset
PCI: Support SR-IOV on any function type
* pci/vpd:
PCI: Prevent VPD access for buggy devices
PCI: Sleep rather than busy-wait for VPD access completion
PCI: Fold struct pci_vpd_pci22 into struct pci_vpd
PCI: Rename VPD symbols to remove unnecessary "pci22"
PCI: Remove struct pci_vpd_ops.release function pointer
PCI: Move pci_vpd_release() from header file to pci/access.c
PCI: Move pci_read_vpd() and pci_write_vpd() close to other VPD code
PCI: Determine actual VPD size on first access
PCI: Use bitfield instead of bool for struct pci_vpd_pci22.busy
PCI: Allow access to VPD attributes with size 0
PCI: Update VPD definitions
Clean up style issues in drivers/pci/pcie/Kconfig, in particular all
indentation is now done using tabs, not spaces, and the definition of
PCIEASPM_DEBUG is now separated from the definition of PCIEASPM with a
newline.
Signed-off-by: Andreas Ziegler <andreas.ziegler@fau.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Log successful error injections so that injected errors can be
differentiated from real errors.
Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Borislav Petkov <bp@suse.de>
The aer_inject driver is very quiet. In most cases, it merely returns an
error code to user-space, leaving the user with little clue about the
actual reason for the failure.
So, log error messages for 4 of the most frequent causes of failure:
* Can't find the root port of the specified device.
* Device doesn't support AER.
* Root port doesn't support AER.
* AER device not found.
This gives the user a chance to understand why aer-inject failed.
Based on a preliminary patch by Thomas Renninger.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Borislav Petkov <bp@suse.de>
CC: Thomas Renninger <trenn@suse.de>
dev_warn() is better than printk(LOG_WARNING...) as it records which device
the message relates to. Also add a prefix "aer_inject:" to help
differentiate real errors from injected errors.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Borislav Petkov <bp@suse.de>
EPERM means "Operation not permitted", which doesn't reflect the lack of
support for AER. EPROTONOSUPPORT (Protocol not supported) is a better
choice of error code if the device or its root port lack support for AER.
Likewise, EINVAL means "Invalid argument", which is not suitable for cases
where the AER error device is missing or unusable. ENODEV and
EPROTONOSUPPORT, respectively, fit better.
Suggested-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Borislav Petkov <bp@suse.de>
CC: Prarit Bhargava <prarit@redhat.com>
* pci/aer:
PCI/AER: Use list_first_entry_or_null() to simplify code
PCI/AER: Restore pci_ops pointer while calling original pci_ops
PCI/AER: Rename pci_ops_aer to aer_inj_pci_ops
* pci/misc:
PCI: Remove includes of asm/pci-bridge.h
PCI: Remove empty asm-generic/pci-bridge.h
ARM64: PCI: Remove generated include of asm-generic/pci-bridge.h
PCI: Remove includes of empty asm-generic/pci-bridge.h
PCI: Move pci_set_flags() from asm-generic/pci-bridge.h to linux/pci.h
PCI/PME: Restructure pcie_pme_suspend() to prevent compiler warning
PCI/PME: Remove redundant port lookup
PCI: Check device_attach() return value always
* pci/virtualization:
PCI: Add ACS quirk for all Cavium devices
Previously we had this:
if (wakeup)
ret = enable_irq_wake(...);
if (!wakeup || ret)
...
"ret" is only evaluated when "wakeup" is true, and it is always initialized
in that case, but gcc isn't smart enough to figure that out and warns:
drivers/pci/pcie/pme.c:414:14: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
Restructure the code slightly to make it easier for gcc (and maybe for
humans as well).
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com
We've already looked up srv->port a few lines earlier, and there's no need
to do it again. Remove the redundant lookup.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com
Use list_first_entry_or_null() instead of list_empty() + list_entry() to
simplify the code.
Signed-off-by: Geliang Tang <geliangtang@163.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
The aer_inject module intercepts config space accesses by replacing the
bus->ops pointer. If it forwards accesses to the original pci_ops, and
those original ops use bus->ops, they see the aer_pci_ops instead of their
own pci_ops, which can cause a crash.
For example, pci_generic_config_read() uses the bus->ops->map_bus pointer.
If bus->ops is set to aer_pci_ops, which doesn't supply .map_bus,
pci_generic_config_read() will dereference an invalid pointer and cause a
crash.
Temporarily restore the original bus->ops pointer while calling ops->read()
or ops->write(). Callers of these functions already hold pci_lock, which
prevents other users of bus->ops until we're finished.
[bhelgaas: changelog]
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Rename
pci_ops_aer to aer_inj_pci_ops
pci_read_aer() to aer_inj_read_config()
pci_write_aer() to aer_inj_write_config()
This is more conventional and more informative. No functional change.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
A Root Port's AER structure (rpc) contains a queue of events. aer_irq()
enqueues AER status information and schedules aer_isr() to dequeue and
process it. When we remove a device, aer_remove() waits for the queue to
be empty, then frees the rpc struct.
But aer_isr() references the rpc struct after dequeueing and possibly
emptying the queue, which can cause a use-after-free error as in the
following scenario with two threads, aer_isr() on the left and a
concurrent aer_remove() on the right:
Thread A Thread B
-------- --------
aer_irq():
rpc->prod_idx++
aer_remove():
wait_event(rpc->prod_idx == rpc->cons_idx)
# now blocked until queue becomes empty
aer_isr(): # ...
rpc->cons_idx++ # unblocked because queue is now empty
... kfree(rpc)
mutex_unlock(&rpc->rpc_mutex)
To prevent this problem, use flush_work() to wait until the last scheduled
instance of aer_isr() has completed before freeing the rpc struct in
aer_remove().
I reproduced this use-after-free by flashing a device FPGA and
re-enumerating the bus to find the new device. With SLUB debug, this
crashes with 0x6b bytes (POISON_FREE, the use-after-free magic number) in
GPR25:
pcieport 0000:00:00.0: AER: Multiple Corrected error received: id=0000
Unable to handle kernel paging request for data at address 0x27ef9e3e
Workqueue: events aer_isr
GPR24: dd6aa000 6b6b6b6b 605f8378 605f8360 d99b12c0 604fc674 606b1704 d99b12c0
NIP [602f5328] pci_walk_bus+0xd4/0x104
[bhelgaas: changelog, stable tag]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: stable@vger.kernel.org
* pci/host-vmd:
x86/PCI: Add driver for Intel Volume Management Device (VMD)
PCI/AER: Use 32 bit PCI domain numbers
x86/PCI: Allow DMA ops specific to a PCI domain
irqdomain: Export irq_domain_set_info() for module use
genirq/MSI: Relax msi_domain_alloc() to support parentless MSI irqdomains
The Intel Volume Management Device (VMD) supports 32-bit domain numbers.
To accommodate this, use u32 instead of u16 to store domain numbers.
[bhelgaas: changelog]
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
* pci/aspm:
PCI/ASPM: Make sysfs link_state_store() consistent with link_state_show()
* pci/hotplug:
PCI: pciehp: Always protect pciehp_disable_slot() with hotplug mutex
* pci/misc:
x86/PCI: Simplify pci_bios_{read,write}
PCI: Simplify config space size computation
PCI: Limit config space size for Netronome NFP6000 family
PCI: Add Netronome vendor and device IDs
PCI: Support PCIe devices with short cfg_size
x86/PCI: Clarify AMD Fam10h config access restrictions comment
PCI: Print warnings for all invalid expansion ROM headers
PCI: Check for PCI_HEADER_TYPE_BRIDGE equality, not bitmask
* pci/msi:
PCI/MSI: Remove empty pci_msi_init_pci_dev()
PCI/MSI: Initialize MSI capability for all architectures
Bit 7 of the "Header Type" register indicates a multi-function device when
set. Bits 0-6 contain encoded values, where 0x1 indicates a PCI-PCI
bridge. It is incorrect to test this as though it were a mask.
For example, while the PCI 3.0 spec only defines values 0x0, 0x1, and 0x2,
it's conceivable that a future spec could define 0x3 to mean something
else; then tests for "(hdr_type & 0x7f) & PCI_HEADER_TYPE_BRIDGE" would
incorrectly succeed for this new 0x3 header type.
Test bits 0-6 of the Header Type for equality with PCI_HEADER_TYPE_BRIDGE.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>