linux/drivers/pci/controller/dwc
Niklas Cassel c22533c66c PCI: dwc: ep: Flush MSI-X write before unmapping its ATU entry
Endpoint drivers use dw_pcie_ep_raise_msix_irq() to raise an MSI-X
interrupt to the host using a writel(), which generates a PCI posted write
transaction.  There's no completion for posted writes, so the writel() may
return before the PCI write completes.  dw_pcie_ep_raise_msix_irq() also
unmaps the outbound ATU entry used for the PCI write, so the write races
with the unmap.

If the PCI write loses the race with the ATU unmap, the write may corrupt
host memory or cause IOMMU errors, e.g., these when running fio with a
larger queue depth against nvmet-pci-epf:

  arm-smmu-v3 fc900000.iommu:      0x0000010000000010
  arm-smmu-v3 fc900000.iommu:      0x0000020000000000
  arm-smmu-v3 fc900000.iommu:      0x000000090000f040
  arm-smmu-v3 fc900000.iommu:      0x0000000000000000
  arm-smmu-v3 fc900000.iommu: event: F_TRANSLATION client: 0000:01:00.0 sid: 0x100 ssid: 0x0 iova: 0x90000f040 ipa: 0x0
  arm-smmu-v3 fc900000.iommu: unpriv data write s1 "Input address caused fault" stag: 0x0

Flush the write by performing a readl() of the same address to ensure that
the write has reached the destination before the ATU entry is unmapped.

The same problem was solved for dw_pcie_ep_raise_msi_irq() in commit
8719c64e76 ("PCI: dwc: ep: Cache MSI outbound iATU mapping"), but there
it was solved by dedicating an outbound iATU only for MSI. We can't do the
same for MSI-X because each vector can have a different msg_addr and the
msg_addr may be changed while the vector is masked.

Fixes: beb4641a78 ("PCI: dwc: Add MSI-X callbacks handler")
Signed-off-by: Niklas Cassel <cassel@kernel.org>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260211175540.105677-2-cassel@kernel.org
2026-02-25 15:44:20 -06:00
..
Kconfig PCI: dwc: tegra194: Broaden architecture dependency 2026-01-08 09:55:00 +05:30
Makefile Merge branch 'pci/controller/spacemit-k1' 2025-12-03 14:18:44 -06:00
pci-dra7xx.c PCI: dwc: Advertise dynamic inbound mapping support 2026-01-28 19:16:06 +05:30
pci-exynos.c PCI: dwc: Add support for ELBI resource mapping 2025-09-25 18:33:37 +05:30
pci-imx6.c Merge branch 'pci/controller/dwc-imx6' 2026-02-06 17:09:35 -06:00
pci-keystone.c PCI: dwc: Advertise dynamic inbound mapping support 2026-01-28 19:16:06 +05:30
pci-layerscape-ep.c PCI: layerscape-ep: Use the generic dw_pcie_ep_linkdown() API to handle Link Down event 2024-07-09 18:21:11 -05:00
pci-layerscape.c PCI: layerscape: Fix arg_count to syscon_regmap_lookup_by_phandle_args() 2025-03-27 13:11:14 -05:00
pci-meson.c PCI: meson: Report that link is up while in ASPM L0s and L1 states 2026-01-05 11:20:29 -06:00
pcie-al.c PCI: dwc: Support ECAM mechanism by enabling iATU 'CFG Shift Feature' 2025-09-25 18:34:01 +05:30
pcie-amd-mdb.c PCI: amd-mdb: Add support for PCIe RP PERST# signal handling 2025-08-11 16:09:45 +05:30
pcie-armada8k.c PCI: dwc: Return bool from link up check 2025-05-13 10:12:59 +01:00
pcie-artpec6.c PCI: dwc: Advertise dynamic inbound mapping support 2026-01-28 19:16:06 +05:30
pcie-bt1.c PCI: controller: Switch back to struct platform_driver::remove() 2024-10-03 16:44:49 -05:00
pcie-designware-debugfs.c PCI: dwc: Rename and move ltssm_status_string() to pcie-designware.c 2026-01-21 14:45:19 +05:30
pcie-designware-ep.c PCI: dwc: ep: Flush MSI-X write before unmapping its ATU entry 2026-02-25 15:44:20 -06:00
pcie-designware-host.c pci-v7.0-changes 2026-02-11 17:20:38 -08:00
pcie-designware-plat.c PCI: dwc: Advertise dynamic inbound mapping support 2026-01-28 19:16:06 +05:30
pcie-designware.c PCI: dwc: Fix missing iATU setup when ECAM is enabled 2026-02-05 18:23:30 +05:30
pcie-designware.h pci-v7.0-changes 2026-02-11 17:20:38 -08:00
pcie-dw-rockchip.c Merge branch 'pci/controller/dwc-rockchip' 2026-02-06 17:09:47 -06:00
pcie-fu740.c PCI: dwc: Drop host prefix from struct dw_pcie_host_ops members 2024-01-06 07:51:08 +00:00
pcie-hisi.c PCI: host-common: Convert to library for host controller drivers 2025-05-30 12:21:57 -05:00
pcie-histb.c PCI: dwc: Return bool from link up check 2025-05-13 10:12:59 +01:00
pcie-intel-gw.c PCI: intel-gw: Remove intel_pcie_cpu_addr() 2025-03-24 14:58:35 -05:00
pcie-keembay.c PCI: dwc: Advertise dynamic inbound mapping support 2026-01-28 19:16:06 +05:30
pcie-kirin.c PCI: dwc: Return bool from link up check 2025-05-13 10:12:59 +01:00
pcie-nxp-s32g.c PCI: s32g: Skip Root Port removal during success 2026-02-03 18:26:27 +05:30
pcie-qcom-common.c PCI: qcom: Fix macro typo for CURSOR 2025-09-04 22:25:22 +05:30
pcie-qcom-common.h PCI: qcom: Add equalization settings for 8.0 GT/s and 32.0 GT/s 2025-09-04 22:24:04 +05:30
pcie-qcom-ep.c Merge branch 'pci/controller/dwc-qcom-ep' 2026-02-06 17:09:47 -06:00
pcie-qcom.c pci-v7.0-changes 2026-02-11 17:20:38 -08:00
pcie-rcar-gen4.c PCI: dwc: Advertise dynamic inbound mapping support 2026-01-28 19:16:06 +05:30
pcie-sophgo.c PCI: sophgo: Disable L0s and L1 on Sophgo 2044 PCIe Root Ports 2026-01-13 20:17:43 +05:30
pcie-spacemit-k1.c PCI: spacemit: Add SpacemiT PCIe host driver 2025-11-17 18:59:03 +05:30
pcie-spear13xx.c PCI: dwc: Return bool from link up check 2025-05-13 10:12:59 +01:00
pcie-stm32-ep.c PCI: dwc: Advertise dynamic inbound mapping support 2026-01-28 19:16:06 +05:30
pcie-stm32.c PCI: stm32: Don't use 'proxy' headers 2025-11-17 14:38:52 -06:00
pcie-stm32.h PCI: stm32: Don't use 'proxy' headers 2025-11-17 14:38:52 -06:00
pcie-tegra194-acpi.c PCI: dwc: Simplify in/outbound iATU setup methods 2022-08-01 15:15:09 -05:00
pcie-tegra194.c PCI: dwc: Advertise dynamic inbound mapping support 2026-01-28 19:16:06 +05:30
pcie-uniphier-ep.c PCI: dwc: Advertise dynamic inbound mapping support 2026-01-28 19:16:06 +05:30
pcie-uniphier.c pci-v6.16-changes 2025-06-04 11:26:17 -07:00
pcie-visconti.c PCI: dwc: Return bool from link up check 2025-05-13 10:12:59 +01:00