summaryrefslogtreecommitdiff
path: root/drivers/cxl/core
AgeCommit message (Collapse)Author
23 hoursMerge branch 'next' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl.git
45 hoursMerge branch 'for-7.4/cxl-dcd' into cxl-for-nextDave Jiang
Part 1 of DCD support. Functionality disabled. Documentation/cxl: Document DPA partition layout and ordering rules cxl/core: Enforce partition order/simplify partition calls cxl/mem: Configure dynamic capacity interrupts cxl/pci: Factor out interrupt policy check cxl/events: Split event msgnum configuration from irq setup cxl/cdat: Gather DSMAS data for DCD partitions cxl/mem: Read dynamic capacity configuration from the device cxl/mbox: Flag support for Dynamic Capacity Devices (DCD)
3 dayscxl/core: Enforce partition order/simplify partition callsIra Weiny
Device partitions share one flat DPA space in a fixed order: static volatile capacity at DPA 0, static persistent capacity immediately above it, and dynamic capacity above all static capacity. The static pair is mandated by CXL r4.0 8.2.10.9.2.1 "Get Partition Info", Table 8-310: the device "shall provide this volatile capacity starting at DPA 0" and "shall provide this persistent capacity starting at the DPA immediately following the volatile capacity". Dynamic capacity has no such rule. Table 8-347 only requires the region base to be 256M aligned, so placing it directly above static capacity is a Linux requirement, enforced by cxl_configure_dcd(). DPA 0 end +---------------+---------------+---------------------------+ | ram | pmem | dynamic_ram_1 | +---------------+---------------+---------------------------+ part[0] part[1] part[2] Signed-off-by: Ira Weiny <iweiny@kernel.org> Co-developed-by: Anisa Su <anisa.su@samsung.com> Signed-off-by: Anisa Su <anisa.su@samsung.com> Tested-by: Wonjae Lee <wj28.lee@samsung.com> Tested-by: Junhee Park <jh9934.park@samsung.com> Tested-by: Heesoo Kim <habil.kim@samsung.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20261010225852.10727-8-anisa.su@samsung.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
3 dayscxl/cdat: Gather DSMAS data for DCD partitionsIra Weiny
Additional DCD partition (AKA region) information is contained in the DSMAS CDAT tables, including performance, shareable and read-only attributes. Match DCD partitions with DSMAS tables and store the meta data. A DCD shall describe its DC partition in a DSMAS entry (CXL r4.0 9.13.3), so if the CDAT is absent, fails to parse, or has no entry matching the DC partition, disable DCD rather than run with unknown attributes. DSLBIS is optional, but cxl_cdat_endpoint_process() treated zero DSLBIS entries as a parse failure, which would now disable DCD on a device with a valid DSMAS. Accept an empty DSLBIS, and skip DSMAS entries with no DSLBIS coordinates. Signed-off-by: Ira Weiny <iweiny@kernel.org> Co-developed-by: Anisa Su <anisa.su@samsung.com> Signed-off-by: Anisa Su <anisa.su@samsung.com> Tested-by: Wonjae Lee <wj28.lee@samsung.com> Tested-by: Junhee Park <jh9934.park@samsung.com> Tested-by: Heesoo Kim <habil.kim@samsung.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://patch.msgid.link/20261010225852.10727-4-anisa.su@samsung.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
3 dayscxl/mem: Read dynamic capacity configuration from the deviceIra Weiny
Devices which support Dynamic Capacity (DC) are configured via mailbox commands. CXL r4.0 section 9.13.3 describes the use of the Get DC Configuration command in order to obtain DCD partition characteristics. Implement the DC mailbox commands as specified in CXL 4.0 section 8.2.10.9.9 (opcodes 48XXh) to read and store the DCD configuration information. Disable DCD if an invalid configuration is found. Initial enablement for Linux only supports one dynamic capacity partition. Read all the partitions the device reports but validate only the first, and configure it as 'dynamic ram'. The specification requires that volatile capacity starts at DPA 0 and pmem starts at the DPA immediately following it, but DC partitions only need to be 256MB aligned according to CXL r4.0 section 8.2.10.9.9.1 Table 8-347. So a device could leave a gap between ram/pmem (static) capacity and its first DC partition, or between one DC partition and the next. However, Linux chooses not to support gaps between static and dynamic capacity, and requires the first DC partition to begin at the DPA immediately following static capacity. Based on an original patch by Navneet Singh. [ dj: Fixed up output line wrapping. (Jonathan) ] [ dj: Fixed up cleanup declaration. (Jonathan) ] [ dj: Remove start_partition in cxl_get_dc_config. (Jonathan) ] Signed-off-by: Ira Weiny <iweiny@kernel.org> Co-developed-by: Anisa Su <anisa.su@samsung.com> Signed-off-by: Anisa Su <anisa.su@samsung.com> Tested-by: Wonjae Lee <wj28.lee@samsung.com> Tested-by: Junhee Park <jh9934.park@samsung.com> Tested-by: Heesoo Kim <habil.kim@samsung.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://patch.msgid.link/20261010225852.10727-3-anisa.su@samsung.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
3 dayscxl/mbox: Flag support for Dynamic Capacity Devices (DCD)Ira Weiny
Per the CXL 4.0 specification software must check the Command Effects Log (CEL) for dynamic capacity command support. Detect support for the DCD commands while reading the CEL, including: Get DC Config Get DC Extent List Add DC Response Release DC Leave mds->dcd_supported false. Dynamic capacity is only usable once the driver can handle Add and Release Capacity events. Detect and log the capability here and let the commit which adds DCD event handling set the flag. Based on an original patch by Navneet Singh. Signed-off-by: Ira Weiny <iweiny@kernel.org> Signed-off-by: Anisa Su <anisa.su@samsung.com> Tested-by: Wonjae Lee <wj28.lee@samsung.com> Tested-by: Junhee Park <jh9934.park@samsung.com> Tested-by: Heesoo Kim <habil.kim@samsung.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Gregory Price (Meta) <gourry@gourry.net> Reviewed-by: Davidlohr Bueso <dave@stgolabs.net> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Tested-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20261010225852.10727-2-anisa.su@samsung.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
6 daysMerge branch 'for-7.4/cxl-fixes' into cxl-for-nextDave Jiang
perf coordinates fixes: cxl/acpi: Convert QTG _DSM latencies to picoseconds cxl: Account for link width in latency calculation cxl/port: Convert PCIe link latency to nanoseconds GPF path fixes: cxl/pci: Update only the Port GPF timeout fields cxl/pci: Program the Port GPF timeouts before caching the DVSEC cxl/pci: Use the Device GPF DVSEC for restricted endpoints dport fixes: cxl/port: Attach endpoints to a dport under the lock that pins it cxl/core: Hold the dport host lock across dport lookup and use cxl/port: Clear cached dport pointers when a dport is removed
6 dayscxl: Account for link width in latency calculationKoichiro Den
cxl_pci_get_latency() derives bandwidth from the per-lane speed returned by pcie_link_speed_mbps(), ignoring the negotiated link width. This overestimates the FlitLatency contribution for multi-lane links. Sections 2.11.3 and 2.11.4 of the Intel CXL Memory Device Software Guide describe the link bandwidth as the product of the negotiated speed and width. Replace pcie_link_speed_mbps() with pcie_link_bandwidth_mbps() and migrate both CXL callers (the only users of the API). The new helper obtains speed and width from a single Link Status read. The CXL bandwidth calculation no longer needs a separate width read and multiplication. While at it, make error handling more robust by converting PCI config read errors to negative errno values and checking for zero bandwidth before calculating latency. Fixes: 4d07a05397c8 ("cxl: Calculate and store PCI link latency for the downstream ports") Cc: stable@vger.kernel.org Signed-off-by: Koichiro Den <den@valinux.co.jp> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> # pci/pci.c Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://patch.msgid.link/20261009045452.1107921-3-den@valinux.co.jp Signed-off-by: Dave Jiang <dave.jiang@intel.com>
6 dayscxl/port: Convert PCIe link latency to nanosecondsKoichiro Den
Commit 51293c565cf4 ("cxl: Fix incorrect region perf data calculation") converted CDAT latencies to nanoseconds and removed the conversion in cxl_region_perf_data_calculate(), but left PCIe link latencies in picoseconds. This inflates the FlitLatency contribution to region and node latencies by a factor of 1000, exposing incorrect values in sysfs. The resulting abstract distances can incorrectly reverse the memory tier ordering of nodes. Convert the FlitLatency contribution to nanoseconds before adding it to the access coordinates, rounding up as cdat_normalize() does. Fixes: 51293c565cf4 ("cxl: Fix incorrect region perf data calculation") Cc: stable@vger.kernel.org Signed-off-by: Koichiro Den <den@valinux.co.jp> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://patch.msgid.link/20261009045452.1107921-2-den@valinux.co.jp Signed-off-by: Dave Jiang <dave.jiang@intel.com>
6 dayscxl/pci: Update only the Port GPF timeout fieldsGuixin Liu
update_gpf_port_dvsec() rebuilds the phase control register from just the timeout base and scale, so the rest of the register is cleared by the write. The other bits are reserved today and nothing is lost, but the full-register rewrite would clobber any field the spec defines there later. Read-modify-write the register and change only the two timeout fields. Fixes: a52b6a2c1c99 ("cxl/pci: Support Global Persistent Flush (GPF)") Assisted-by: LLM Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20261008034619.28059-4-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
6 dayscxl/pci: Program the Port GPF timeouts before caching the DVSECGuixin Liu
cxl_gpf_port_setup() caches the Port GPF DVSEC offset in the dport before programming the phase timeouts, and ignores the return value of both update_gpf_port_dvsec() calls: the function always reports success. A failing config write is therefore not only silent, it is also permanent: the timeouts stay at the hardware defaults instead of the maximum flush window the kernel is asking for, and the cached offset keeps any later endpoint attach from retrying the update. Propagate the errors and cache the offset only after both phases are programmed, so the next endpoint attach retries the setup. Fixes: 6af941db6a60 ("cxl/pci: Update Port GPF timeout only when the first EP attaching") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20261008034619.28059-3-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
6 dayscxl/pci: Use the Device GPF DVSEC for restricted endpointsGuixin Liu
cxl_gpf_get_dvsec() picks between the Port and the Device GPF DVSEC from the PCIe type of the given device, and only a plain endpoint counts as a device. A restricted CXL device is an endpoint too, but it falls into the port case and is probed for the Port GPF DVSEC instead of the Device GPF DVSEC. On an RCD, dirty shutdown tracking therefore never arms: the DVSEC lookup in cxl_nvdimm_arm_dirty_shutdown_tracking() fails, the dirty shutdown count stays invalid, and the warning complains about a missing Port GPF DVSEC on a device. Treat restricted endpoints as devices. Fixes: 36aace15d9bd ("cxl/pci: Drop the parameter is_port of cxl_gpf_get_dvsec()") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20261008034619.28059-2-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
6 dayscxl/port: Attach endpoints to a dport under the lock that pins itDave Jiang
devm_cxl_enumerate_ports() and add_port_attach_ep() look up or create a dport under its port's device lock, drop the lock, then pass the dport to cxl_add_ep(). add_ep() reads dport->port before taking the lock, and cxl_gpf_port_setup() reads and writes the dport with no lock held. A concurrent cxl_detach_ep() for another memdev below the same port can free the dport in that window: it calls del_dports() under the port lock when the last endpoint leaves. The enumerating memdev then dereferences freed memory. Attach the endpoint and set up GPF while the port lock from the lookup is still held. Make add_ep() assert that lock instead of taking it. Under the lock, a dport found in port->dports is still live, since removal erases it from the xarray before freeing it. [ dj: Added kdoc update from Alison. ] Fixes: de516b40116e ("cxl/port: Record dport in endpoint references") Reported-by: Li Ming <ming.li@zohomail.com> Closes: https://lore.kernel.org/linux-cxl/0c68324c-cfc7-46b2-9344-24ae40e88923@zohomail.com/ Assisted-by: LLM Reviewed-by: Li Ming <ming.li@zohomail.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20261001154744.1095902-4-dave.jiang@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
6 dayscxl/core: Hold the dport host lock across dport lookup and useDave Jiang
Callers of cxl_pci_find_port() and cxl_mem_find_port() can be handed a 'struct cxl_dport' that is already freed, and all four dereference it without the lock that would prevent that. A dport is kzalloc()'d into a devres group on its host device, so it dies when that host unbinds. The host is &port->dev for a switch port and port->uport_dev for the root port. Both helpers return the dport through an output parameter. The caller's port reference pins struct cxl_port, not the dport allocation, and the lookup itself is a bare xa_load() under no lock. Add cxl_port_dport_host() to name the device that pins a dport, and cxl_pci_find_dport() / cxl_mem_find_dport() to look one up with that device's lock held and asserted. Convert the four callers to use them and bail if the dport is gone. cxl_port_add_dport() already follows this rule. cxl_mem_probe() chose its endpoint devm host from dport->rch, which meant dereferencing the dport before taking any lock. Use cxl_port_dport_host(): rch dports only ever land on the root port, so it selects the same device without needing the dport. With every caller converted, the dport output parameter of cxl_pci_find_port() and cxl_mem_find_port() is unused. Drop it. Fixes: 733b57f262b0 ("cxl/pci: Early setup RCH dport component registers from RCRB") Assisted-by: LLM Reviewed-by: Li Ming <ming.li@zohomail.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20261001154744.1095902-3-dave.jiang@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
6 dayscxl/port: Clear cached dport pointers when a dport is removedDave Jiang
Switch decoders cache dport pointers in cxlsd->target[], and nothing clears them when a dport is freed. Readers then dereference freed memory. KASAN caught it under a cxl_test load/unload loop with concurrent sysfs reads (abbreviated). Clear the matching slots from cxl_dport_remove(), walking the port's decoders the way cxl_port_update_decoder_targets() does on the add side. Scan all nr_targets slots, the target[] allocation size, and clear every hit. Fixes: 8330671c57c7 ("cxl: Add helper to delete dport") Cc: stable@vger.kernel.org Assisted-by: LLM Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Li Ming <ming.li@zohomail.com> Reviewed-by: Gregory Price (Meta) <gourry@gourry.net> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20261001154744.1095902-2-dave.jiang@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
14 daysPCI/AER: Map a raw AER Capability image field by fieldDave Jiang
struct aer_capability_regs is not the hardware layout: the embedded struct pcie_tlp_log spans 60 bytes where the Header Log it stands in for is 16, so a flat copy misplaces everything behind it. extlog_print_pcie(), ghes_handle_aer() and cxl_rch_get_aer_info() work around that by stopping at the Header Log, dropping everything past offset 44. Flit mode is never decoded either: the Flit bit and Logged TLP Size sit at offset 0x18, unread, so the Flit DWORDs at 0x38 are lost and the log prints as non-Flit. Add aer_cap_regs_unpack() to map the registers individually, taking the TLP Log layout from the Flit bit as pcie_read_tlp_log() does. Clamp the logged length: Logged TLP Size is 5 bits wide, so an untrusted value reaches 31 where dw[] holds 14 and pcie_print_tlp_log() walks header_len unbounded. Take the image little-endian, as both sources are: CPER by definition, PCIe registers on the wire. Read it with get_unaligned_le32(), since a CPER section sits wherever firmware put it, and take the two source IDs out of the Error Source Identification register by bit position rather than byte offset. cxl_rch_get_aer_info() uses readl(), so it hands back __le32. Convert all three callers. cxl_rch_get_aer_info() now reads the whole MMIO block, so size its ioremap by the hardware registers (96 bytes) rather than by sizeof(struct aer_capability_regs) (100). Shrinking the mapping is safe: the read it replaces stopped at 44 bytes. Reported-by: sashiko-bot@kernel.org Closes: https://sashiko.dev/#/patchset/20260904172337.1409775-1-dave.jiang@intel.com?part=5 Link: https://lore.kernel.org/linux-cxl/CAJZ5v0hDv11cPuztPZsaDd7uwD_49KznJy=tzuRO+dZc=CnAEQ@mail.gmail.com/ Assisted-by: LLM Signed-off-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://patch.msgid.link/20260911164705.841407-1-dave.jiang@intel.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-09-29Merge branch 'for-7.4/cxl-misc' into cxl-for-nextDave Jiang
cxl/region: Warn on user region position mismatch
2026-09-29cxl/region: Warn on user region position mismatchAlison Schofield
User region creation includes a self-test that checks the assigned endpoint positions against the position calculation used by auto region creation. The result, matching or not, is reported with dev_dbg(). Promote that to a dev_warn() that fires only on a mismatch, so bugs in the auto region position calculation are easier to catch as that calculation is extended to support more region configurations. The matching case no longer prints, so dynamic debug on region.c no longer confirms that the self-test ran. Signed-off-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Robert Richter <rrichter@amd.com> Link: https://patch.msgid.link/1d662e3ea78ec8b05fceb500f04e69ee9f6d4a72.1788475206.git.alison.schofield@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-18Merge branch 'for-7.4/cxl-fixes' into cxl-for-nextDave Jiang
cxl/core: Skip einj_inject creation when devm_add_action_or_reset() fails cxl/events: Return IRQ_NONE when no event is pending cxl/region: Create node access attributes for CFMWS-only NUMA nodes
2026-09-18cxl/core: Skip einj_inject creation when devm_add_action_or_reset() failsGuixin Liu
cxl_debugfs_create_dport_dir() ignores the devm_add_action_or_reset() result and creates the einj_inject file below @dir unconditionally. When the devres allocation fails, remove_debugfs() has already run before devm_add_action_or_reset() returns, i.e. debugfs_remove() has released @dir. The subsequent debugfs_create_file() would then use that dentry as its parent although its final reference was dropped in the removal and its memory is subject to call_rcu() delayed freeing. Skip the file creation in that case, consistent with how the rest of the helper tolerates debugfs failures. Fixes: 9185b1a3043c ("cxl/core: Fix dport use-after-free via the einj_inject debugfs file") Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Li Ming <ming.li@zohomail.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://patch.msgid.link/20260915060138.2007974-1-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-18cxl/region: Create node access attributes for CFMWS-only NUMA nodesGuixin Liu
A NUMA node that only backs a CXL fixed memory window and is not enumerated by SRAT has no memory_target in the HMAT code, so hmat_callback() exits early at find_mem_target() and never creates the node's accessN attributes: /sys/devices/system/node/nodeX/accessN/initiators/* stays missing. Commit debdce20c4f2 ("cxl/region: Deal with numa nodes not enumerated by SRAT") had the CXL region notifier call node_set_perf_attrs() directly for such nodes, but commit 2e454fb8056d ("cxl, acpi/hmat: Update CXL access coordinates directly instead of through HMAT") replaced it with node_update_perf_attrs(), which only updates attributes that already exist and thus does nothing for these nodes. Create the attributes with node_set_perf_attrs() when the node is not backed by a real SRAT pxm. Tested on a QEMU CXL topology with a CFMWS window not described by SRAT or HMAT: node1/access0/initiators/{read,write}_{bandwidth,latency} appear with the calculated coordinates once the region's first memory block comes online. Fixes: 2e454fb8056d ("cxl, acpi/hmat: Update CXL access coordinates directly instead of through HMAT") Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Gregory Price (Meta) <gourry@gourry.net> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260917024632.1397380-1-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-17Merge branch 'for-7.4/decoder_hardening' into cxl-for-nextDave Jiang
Sashiko reported issues on decoders: cxl/port: Bound switch decoder target array access by nr_targets cxl/hdm: Restore commit_end when decoder enumeration fails cxl/hdm: Make switch decoder target parsing endian-safe cxl/hdm: Reject switch decoder interleave ways that overflow targets
2026-09-17Merge branch 'for-7.4/cxl-zero-size-decoder' into cxl-for-nextDave Jiang
Enable zero sized decoders cxl/test: Enable zero sized decoders under hb0 cxl/hdm: Allow zero sized HDM decoders cxl/region: Simplify poison_by_decoder() error handling
2026-09-17Merge branch 'for-7.4/cxl-misc' into cxl-for-nextDave Jiang
cxl/region: Fix the return value in devm_cxl_add_region() kernel-doc cxl/regs: Reject register blocks in an unassigned BAR MAINTAINERS: Add Richard Cheng to CXL subsystem as a Reviewer cxl: docs/platform/acpi: Fix brackets cxl/region: Guard against a missing peer mapping
2026-09-17cxl/region: Unregister the pmem region when the bridge is unboundGuixin Liu
Removing cxl_acpi unbinds the nvdimm bridge before the regions it serves. A region probe can therefore register its cxl_pmem_region and only then find the bridge unbound, which leaves the new device with nothing to remove it. The orphan outlives the teardown and pins its region and its memdevs, so a later cxl_acpi bind renumbers the root port, ports, endpoints, decoders and the memdev. Unregister the cxl_pmem_region when the bridge is unbound. Found by code inspection. Racing a cxl_region bind against a cxl_acpi unbind leaked a pmem_region device on 12 of 12 attempts, and none with this patch. Fixes: f17b558d6663 ("cxl/pmem: Refactor nvdimm device registration, delete the workqueue") Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Li Ming <ming.li@zohomail.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://patch.msgid.link/20260831061120.200790-1-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-17cxl/core: Fix dport use-after-free via the einj_inject debugfs fileGuixin Liu
The per-dport einj_inject debugfs file retains a pointer to the 'struct cxl_dport', but its lifetime is not tied to the dport. Unbinding the dport host frees the dport and leaves einj_inject behind, so writing the file dereferences freed memory. The stale directory also prevents recreation on rebind. Remove the per-dport debugfs directory when the dport host is released. Found by code inspection, then reproduced on a QEMU CXL topology with KASAN (the einj_cxl_is_initialized() guard had to be forced open, as QEMU emits no EINJ table). Unpatched, writing the leftover file after unbind gives a KASAN slab-use-after-free report in cxl_einj_inject(), and rebind hits "already exists in 'cxl'". Patched, the directory goes away with the dport and rebind recreates a working einj_inject. Fixes: 8039804cfa73 ("cxl/core: Add CXL EINJ debugfs files") Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Li Ming <ming.li@zohomail.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260914121843.718493-1-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-17cxl/port: Fix uninitialized coordinates reported for RCDsGuixin Liu
cxl_endpoint_get_perf_coordinates() returns success for a Restricted CXL Device without calculating coordinates, so the caller's output array is left uninitialized. Callers treat it as valid and can expose the stack residue as access coordinates. Initialize the coordinates to zero before returning for an RCD. Zeroing in the helper rather than at the caller keeps the @coord output contract the exported function documents. Reported by the Sashiko review bot. Fixes: 5d211c709059 ("cxl: Fix cxl_endpoint_get_perf_coordinate() support for RCH") Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://patch.msgid.link/20260831092216.540644-3-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-17cxl/cdat: Fix uninitialized stack use in bandwidth gatheringGuixin Liu
cxl_endpoint_gather_bandwidth() and cxl_switch_gather_bandwidth() declare access_coordinate arrays on the stack and rely on their helpers to fill them. The helpers assign only the bandwidth members, and the combine step assigns even those only when both inputs are non-zero. The latency members are summed from stack residue on every call, and the bandwidth members keep that residue into the region access coordinate sysfs attributes when the endpoint CDAT reports no bandwidth. Zero initialize the arrays. Zero is the value this code already uses for "not reported", so an unset member now reads back as unknown rather than as a plausible number. Found by code inspection. Tested on a QEMU CXL topology with two endpoints sharing a switch upstream link and HMAT generic-port coordinates for the host bridge, which the calculation requires to run at all: with temporary printk at the combine sites, the unpatched kernel summed 0xfefefefe, the CONFIG_INIT_STACK_ALL_PATTERN stack filler, into the latency members, while the patched kernel reports the CDAT latency values there. Fixes: a5ab0de0ebaa ("cxl: Calculate region bandwidth of targets with shared upstream link") Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://patch.msgid.link/20260831092216.540644-2-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-17cxl/features: Ensure that count is set before access to ent[] __counted_by()Ashok Raj
get_supported_features() assigns entries->num_features only after the memcpy() loop that fills entries->ent[] has already run. Since ent[] is __counted_by(num_features), the compiler's bounds instrumentation sees a 0-length array during that loop and FORTIFY_SOURCE trips on the memcpy. Set @num_features right after allocation, before any write into ent[], so the bound is correct for the whole lifetime of the array. This was found via a fortify panic: memcpy: detected buffer overflow: 384 byte write of buffer size 0 WARNING: lib/string_helpers.c:1035 at __fortify_report+0x54/0xa0 kernel BUG at lib/string_helpers.c:1043! Call trace: __fortify_panic+0x10/0x18 get_supported_features.isra.0+0x4a0/0x4d0 [cxl_core] devm_cxl_setup_features+0x84/0x120 [cxl_core] cxl_pci_probe+0x254/0x5e0 [cxl_pci] Same class of bug, same fix shape as commit 6c9d2e87df40 ("cxl/fwctl: Fix __fortify_panic"), which fixed the analogous issue in cxlctl_get_supported_features() but missed this one. [ dj: Fixed up title typo per Jonathan. ] Fixes: f0e6a2329bf9 ("cxl: Add Get Supported Features command for kernel usage") Signed-off-by: Ashok Raj <ashok.raj@oss.qualcomm.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://patch.msgid.link/20260911215304.1816467-1-ashok.raj@oss.qualcomm.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-17cxl/pci: Skip reset detection for DVSEC emulated decodersGuixin Liu
HDM decoders are emulated from the DVSEC range registers in two cases: (a) the component registers expose no HDM decoder capability, or (b) the capability is present but the DVSEC ranges were the ones in use at driver load. After an FLR or SBR, __cxl_endpoint_decoder_reset_detected() reads the HDM decoder Committed bit for every decoder marked enabled, emulated ones included. In case (a) regs.hdm_decoder is NULL and the read oopses. In case (b) the Committed bit was never set, so a reset gets reported that never happened. Use the absence of cxld->commit to elide the check for emulated decoders. Case (b) tested under QEMU: a reset on an endpoint driven down the DVSEC emulation path no longer reports a reset or strips the decoder flags. Fixes: 934edcd436dc ("cxl: Add post-reset warning if reset results in loss of previously committed HDM decoders") Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://lore.kernel.org/linux-cxl/20260811113608.2815625-1-kanie@linux.alibaba.com/ Link: https://patch.msgid.link/20260831110449.719086-1-kanie@linux.alibaba.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-16cxl/port: Bound switch decoder target array access by nr_targetsAlison Schofield
Switch decoder target lookups walk the target array using interleave ways as the bound. The array is allocated with nr_targets entries, so a decoder whose interleave ways exceeds nr_targets reads and writes past the end of it. That happens during dport activation, during decoder target population, and when userspace reads the target_list attribute. Bounding by nr_targets alone is not correct either. Commit d6488fee6647 ("cxl/port: Fix decoder initialization when nr_targets > interleave_ways") moved target population to interleave ways precisely so that targets a decoder does not use are left unpopulated. Neither field alone is a safe bound, so add a helper that returns the minimum of the two and use it at every walk of the target array. Valid configurations keep interleave ways within nr_targets, so this is not a behavior change for them. Fixes: 40ba17afdfab ("cxl/acpi: Introduce cxl_decoder objects") Fixes: d6488fee6647 ("cxl/port: Fix decoder initialization when nr_targets > interleave_ways") Signed-off-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Li Ming <ming.li@zohomail.com> Link: https://patch.msgid.link/d7577652cc6d414e1de0ee4045d4d6b2808172ce.1786143520.git.alison.schofield@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-16cxl/hdm: Restore commit_end when decoder enumeration failsAlison Schofield
commit_end tracks the highest committed decoder on a port. It gets advanced before decoder enumeration is complete, so a later failure leaves it pointing at a decoder that was never added. The next probe then rejects decoder0 as out of order and enumeration fails. Reset commit_end to the uncommitted baseline once the decoders are torn down, so a subsequent probe rebuilds it from scratch. Register the reset before the decoders are added so that on unwind it runs after every decoder has been unregistered. This prevents commit_end from dropping below the highest committed decoder still registered and exposing an inconsistent value to a concurrent reader. Protect the commit_end advance in the DVSEC emulation path against concurrent readers, matching the register-programmed path. Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware") Fixes: b777e9bec960 ("cxl/hdm: Emulate HDM decoder from DVSEC range registers") Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Li Ming <ming.li@zohomail.com> Reviewed-by: Richard Cheng <icheng@nvidia.com> Signed-off-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/4802c5abc906b858a4754bfc4fa3e4c2c455d0c3.1786143520.git.alison.schofield@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-16cxl/hdm: Make switch decoder target parsing endian-safeAlison Schofield
Switch decoder target IDs are stored one per byte, starting with target 0 in the least significant byte. The current code accesses those bytes in memory order, which only matches register order on little-endian hosts. On big-endian hosts, the target IDs are reversed and the decoder is associated with the wrong downstream ports. Place the register values in a byte array in little-endian order and index the target IDs from there, so the target mapping is independent of host endianness. Fixes: d17d0540a0db ("cxl/core/hdm: Add CXL standard decoder enumeration to the core") Signed-off-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Li Ming <ming.li@zohomail.com> Link: https://patch.msgid.link/b0526825b3c3ffdb78837563e178d9aa27b6bbb8.1786143520.git.alison.schofield@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-16cxl/hdm: Reject switch decoder interleave ways that overflow targetsAlison Schofield
Switch decoder enumeration validates that the interleave ways encoding is legal, but not that the resulting number of ways fits the available targets. This can overrun the target array (target_list.target_id[]) during enumeration of 12 or 16 way interleaves. Bound the target count where it is established rather than at each use. Reject an HDM capability whose reported target count is zero or exceeds the target list register capacity, and reject a zero target switch decoder allocation in cxl_switch_decoder_init(). Enumeration is then left with a single check: reject a decoder whose interleave ways exceed the targets it has. Add a clarifying comment that target_count is a direct count, not 0-based like decoder_count. Link: https://sashiko.dev/#/patchset/20260711180755.1779002-1-alison.schofield@intel.com?part=1 Fixes: d17d0540a0db ("cxl/core/hdm: Add CXL standard decoder enumeration to the core") Tested-by: Davidlohr Bueso <dave@stgolabs.net> Reviewed-by: Davidlohr Bueso <dave@stgolabs.net> Reviewed-by: Richard Cheng <icheng@nvidia.com> Signed-off-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Li Ming <ming.li@zohomail.com> Link: https://patch.msgid.link/af094094813d7f51d86cbf608936270b7d85526e.1786143520.git.alison.schofield@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-15cxl/hdm: Allow zero sized HDM decodersRichard Cheng
CXL r4.0 §8.2.4.20.12 ("Committing Decoder Programming") and §14.13.10 ("CXL HDM Decoder Zero Size Commit") permit committing an HDM decoder with size 0. BIOS may commit and lock such decoders so the OS cannot program regions through them, this is a design choice rather than a spec requirement. The kernel rejected these with -ENXIO during port enumeration and aborted the whole port, so affected systems showed nothing under "cxl list". Treat empty decoders as first class reservations. Back them with a separately allocated resource, since the resource tree cannot represent an empty range, and keep the skip and hdm_end accounting intact. Exclude empty decoders from region assembly and avoid zero-length poison queries. Suggested-by: Dan Williams <djbw@kernel.org> Signed-off-by: Vishal Aslot <vaslot@nvidia.com> Signed-off-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Dan Williams <djbw@kernel.org> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260914090858.19181-3-icheng@nvidia.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-15cxl/region: Simplify poison_by_decoder() error handlingRichard Cheng
"rc" carries both an error code and the loop control signal for device_for_each_child(), so returning it bare is misleading, the early guards mean "keep walking", not "no error". Zeroing "rc" to forgive an -EFAULT on a RAM partition adds to that by discarding what the device actually returned. Return a literal 0 where the walk should continue, and test the forgiven case directly instead of rewriting "rc". Give that test a name, poison_efault_forgiven(), so cxl_get_poison_unmapped() and poison_by_decoder() spell the same rule the same way. No functional change. Suggested-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260914090858.19181-2-icheng@nvidia.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-11cxl/region: Fix the return value in devm_cxl_add_region() kernel-docKarl Mehltretter
devm_cxl_add_region() returns the new struct cxl_region, or an ERR_PTR() on failure, but its kernel-doc says "0 if the region was added to the @cxlrd, else returns negative error code", which was never true. Describe the pointer. [ dj: Dropped Fixes tag as it's a comment fix and not code fix. ] Assisted-by: LLM Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://patch.msgid.link/20260911221748.7212-1-kmehltretter@gmail.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-11cxl/regs: Reject register blocks in an unassigned BARJunjie Cao
cxl_decode_regblock() only checks that the Register Locator offset fits pci_resource_len(). A BAR the PCI core could not place is reset to zero start, end and flags while config space keeps the firmware value, so a zero offset passes and the block is mapped at physical address 0. On x86 ioremap() of the reserved low megabyte succeeds, the component register header does not match, and a switch port fails with "HDM decoder capability not found", pointing at the HDM decoders rather than at the BAR. Reject a BAR with no length or still unassigned, next to the existing size check. Skip empty Register Locator entries first: they decode as BAR0 offset 0 and would trip the check, and nothing looks them up. Seen with edk2-stable202602 (f6489621b8ae, reverted in stable202605), which places 64-bit non-prefetchable BARs behind a bridge in the prefetchable window. Linux refuses to claim them and the switch upstream and downstream port BAR0s find no room in the 32-bit window. QEMU q35 with a CXL switch, Fedora 43 edk2-ovmf-20260213, before: pci 0000:0d:00.0: BAR 0 [mem size 0x00010000 64bit]: can't assign; no space cxl_port port2: HDM decoder capability not found after: pcieport 0000:0d:00.0: BAR0: not assigned (type: 1) cxl_port port2: No component registers mapped cxl_port port2: Failed to map HDM decoder capability Link: https://github.com/tianocore/edk2/issues/13104 Signed-off-by: Junjie Cao <junjie.cao@intel.com> Reviewed-by: Li Ming <ming.li@zohomail.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Link: https://patch.msgid.link/20260910093858.535969-1-junjie.cao@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-04cxl/ras: Make cxl_cper_handle_prot_err() staticDave Jiang
The extlog caller went away when extlog switched to cxl_cper_post_prot_err(), leaving cxl_cper_prot_err_work_fn() in the same file as the only caller. Drop the export and the declaration in <cxl/event.h>, and make it static. Reviewed-by: Hanjun Guo <guohanjun@huawei.com> Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> Link: https://patch.msgid.link/20260904172337.1409775-14-dave.jiang@intel.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-09-04cxl/fwctl: Propagate feature RPC delivery errorsRichard Cheng
FWCTL_RPC requires delivery failures to be returned as ioctl errors, while device errors are reported in the output. Get and Set Feature instead converted all failures into normal responses, sometimes with a SUCCESS device status. Initialize the return code to SUCCESS. When the helper fails without a device error code, return its errno. Continue reporting actual device errors through rpc_out->retval. CXL permits Get Feature to return a nonzero short payload when Offset + Count runs past the end of the Feature. cxl_internal_send_cmd() reports that response as -EIO, so preserve the returned bytes as a successful partial transfer. Fixed-format EDAC callers still require complete attribute structures, so reject partial payloads before consuming them. Map an unexpected zero-length result with a SUCCESS device status to -EIO. Fixes: 5908f3ed6dc2 ("cxl: Add support to handle user feature commands for get feature") Fixes: eb5dfcb9e36d ("cxl: Add support to handle user feature commands for set feature") Signed-off-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260902053839.25595-8-icheng@nvidia.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-04cxl/features: Reject feature offset that overflows 16-bit fieldRichard Cheng
cxl_get_feature() and cxl_set_feature() build each mailbox command's offset from the starting offset plus the amount of data already transferred, then store it in a 16-bit field. A user-controlled fwctl offset and transfer size can exceed the feature extent, allowing a later offset to be truncated by cpu_to_le16() and target the wrong feature data. Reject requests whose transfer size exceeds the remaining 16-bit feature range. Express the check as "size > U16_MAX - offset" so the validation itself cannot wrap on 32-bit systems. Change cxl_get_feature() to return ssize_t so invalid input and mailbox failures are reported as negative errno rather than being conflated with a zero-byte result. Update the EDAC callers to handle negative results. Keep fwctl behavior unchanged by translating helper failures to the same header-only RPC response carrying the CXL mailbox return code. Fixes: 5e5ac21f629d ("cxl/mbox: Add GET_FEATURE mailbox command") Fixes: 14d502cc2718 ("cxl/mbox: Add SET_FEATURE mailbox command") Reviewed-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260902053839.25595-2-icheng@nvidia.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-09-01cxl/ras: Pass the PCI device's struct device to match_memdev_by_parent()Dave Jiang
cxl_cper_handle_prot_err() hands bus_find_device() the 'struct pci_dev' where match_memdev_by_parent() expects the embedded 'struct device'. The comparison never matches. The lookup always fails and CXL endpoint protocol errors reported via CPER are dropped without a trace event, leaving only the root port, downstream and upstream cases reporting. Pass &pdev->dev, and rename the callback parameter to match what it is. Fixes: 3c70ec71abda ("cxl/ras: Fix CPER handler device confusion") Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Terry Bowman <terry.bowman@amd.com> Link: https://patch.msgid.link/20260828215726.1077498-1-dave.jiang@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-08-31cxl/region: Guard against a missing peer mappingAlison Schofield
When two endpoints share a dport, both must be mapped by the port. sashiko-bot reports that a missing peer mapping could result in a NULL pointer dereference during region creation. No caller can reach this today. Guard it anyway so a future violation of the mapping requirement fails region creation rather than causing an oops. Reported-by: sashiko-bot@kernel.org Link: https://sashiko.dev/#/patchset/cover.1787255388.git.alison.schofield%40intel.com?part=3 Assisted-by: Claude:claude-opus-5 Signed-off-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://patch.msgid.link/20260821222515.2675707-1-alison.schofield@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-08-31cxl/mce: Avoid alias page retirement for corrected errorsShaikh Kamaluddin
cxl_handle_mce() offlines the aliased page of an Extended Linear Cache (ELC) region for any MCE with a usable address in the region. This includes corrected errors, needlessly reducing usable memory. Skip ELC alias retirement when mce_is_correctable() identifies the reported error as corrected. Uncorrected errors with a usable address in the ELC region continue to retire the aliased page as before. mce_usable_address() already implements the per-vendor checks that determine whether the reported address is usable, so no separate memory-error classification is needed. On AMD, a corrected legacy bank 4 DRAM ECC error (XEC 8) reports a usable address and retired the aliased page before this change. Tested under QEMU with Intel Skylake-Server and AMD EPYC-Milan models. Fixes: 516e5bd0b6bf ("cxl: Add mce notifier to emit aliased address for extended linear cache") Signed-off-by: Shaikh Kamaluddin <shaikhkamal2012@gmail.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://patch.msgid.link/20260824134957.11085-1-shaikhkamal2012@gmail.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-08-05Merge branch 'for-7.3/cxl-port-err-prep' into cxl-for-nextDave Jiang
cxl: Rename find_cxl_port() to find_cxl_port_by_dport() cxl: Tighten CPER kfifo registration API and symbol visibility acpi/apei/ghes: Use raw_spinlock_t for CXL CPER work locks cxl/ras: Fix cxl_rch_get_aer_severity() wrong severity register cxl/ras: Fix cxl_rch_get_aer_info() out-of-bounds AER register read
2026-08-05cxl: Rename find_cxl_port() to find_cxl_port_by_dport()Dan Williams
find_cxl_port() and find_cxl_port_by_uport() are internal port lookup functions that search the CXL bus by dport and uport respectively, but their names do not make the lookup method clear. Rename find_cxl_port() to find_cxl_port_by_dport() to make the lookup method explicit and consistent with find_cxl_port_by_uport(). Both functions remain static to port.c; the upcoming patch that adds the first cross-file caller will widen their scope. Make the same naming change to static helper __find_cxl_port_by_dport(). Co-developed-by: Terry Bowman <terry.bowman@amd.com> Signed-off-by: Terry Bowman <terry.bowman@amd.com> Signed-off-by: Dan Williams <djbw@kernel.org> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Jonathan Cameron <jic23@kernel.org> Link: https://patch.msgid.link/20260803221810.3685703-6-terry.bowman@amd.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-08-05cxl: Tighten CPER kfifo registration API and symbol visibilityDan Williams
Tighten the CPER protocol error kfifo registration API and symbol visibility. Use EXPORT_SYMBOL_FOR_MODULES() instead of EXPORT_SYMBOL_NS_GPL() for the CPER kfifo registration symbols. This names the consuming module explicitly and gives compile-time enforcement. Drop the work_struct argument from the unregister path. Change the WARN_ONCE condition to a NULL check since there is no caller pointer to compare against anymore. Return void from the registration helpers whose result callers ignore. cxl_cper_register_work() keeps its int return as the only one consumed by a caller. Flag double registration with WARN_ONCE() inside the lock instead of returning an error. Change cxl_ras_init() to void because there is one consumer and one producer so the error return was unnecessary. Remove the now-dead error check in cxl_core_init(). Co-developed-by: Terry Bowman <terry.bowman@amd.com> Signed-off-by: Terry Bowman <terry.bowman@amd.com> Signed-off-by: Dan Williams <djbw@kernel.org> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260803221810.3685703-5-terry.bowman@amd.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-08-05acpi/apei/ghes: Use raw_spinlock_t for CXL CPER work locksTerry Bowman
The CXL CPER work registration and unregistration helpers acquire cxl_cper_work_lock and cxl_cper_prot_err_work_lock with a spinlock guard(), which leaves local interrupts enabled. The corresponding post paths (cxl_cper_post_event(), cxl_cper_post_prot_err()) execute in hard IRQ context (they are called from the GHES error notification path) and acquire the same locks with an irqsave guard(). If a CPU is holding one of these locks via a spinlock guard() when a GHES interrupt arrives on the same CPU, the IRQ handler spins on the held lock waiting for it to release, while the lock holder is preempted by the IRQ. The result is a deadlock. Convert both locks from spinlock_t to raw_spinlock_t and use guard() at all call sites. On PREEMPT_RT kernels spinlock_t is backed by rt_mutex and sleeping from hard IRQ context is not permitted; raw_spinlock_t is safe in both contexts. Add WARN_ONCE to both register functions to surface double-registration bugs at runtime. Restructure both unregister functions to clear the global work pointer under the lock before calling cancel_work_sync(), closing the window where a CPER interrupt could schedule work on a pointer about to be freed. Add kfifo_reset() after cancel_work_sync() so stale entries are not replayed on next module load. Both kfifos are single-consumer: only one work_struct is registered at a time, enforced by the WARN_ONCE guard in the register functions. kfifo_reset() is safe outside the lock because cancel_work_sync() has already quiesced the consumer, and no new consumer can register until the current module exit completes and a fresh module init runs. Remove the redundant cancel_work_sync() call from cxl_ras_exit() and cxl_pci_driver_exit(). The CPER unregister functions now quiesce the work internally. Reported-by: Sashiko <sashiko@linuxfoundation.org> Signed-off-by: Terry Bowman <terry.bowman@amd.com> Fixes: 5e4a264bf8b5 ("acpi/ghes: Process CXL Component Events") Fixes: 36f257e3b0ba ("acpi/ghes, cxl/pci: Process CXL CPER Protocol Errors") Cc: stable@vger.kernel.org Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Tony Luck <tony.luck@intel.com> Link: https://patch.msgid.link/20260803221810.3685703-4-terry.bowman@amd.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-08-05cxl/ras: Fix cxl_rch_get_aer_severity() wrong severity registerTerry Bowman
cxl_rch_get_aer_severity() classifies RCH Downstream Port uncorrectable errors as fatal or non-fatal by ANDing uncorrectable status with PCI_ERR_ROOT_FATAL_RCV. This is wrong because PCI_ERR_ROOT_FATAL_RCV is a Root Error Status register bit (bit 6), not a severity bit. ANDing it against uncorrectable status tests a reserved bit and produces incorrect severity classification. Fix by ANDing the unmasked uncor_status against uncor_severity. Per PCIe Base Spec r6.0 Section 7.8.4.4, each bit in the Uncorrectable Error Severity register indicates whether the corresponding error is fatal (1) or non-fatal (0). Fixes: 6ac07883dbb5 ("cxl/pci: Add RCH downstream port error logging") Cc: stable@vger.kernel.org Signed-off-by: Terry Bowman <terry.bowman@amd.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Richard Cheng <icheng@nvidia.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260803221810.3685703-3-terry.bowman@amd.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
2026-08-05cxl/ras: Fix cxl_rch_get_aer_info() out-of-bounds AER register readTerry Bowman
cxl_rch_get_aer_info() copies the RCH Downstream Port AER capability from the RCRB MMIO block using a readl() loop bounded by sizeof(struct aer_capability_regs). This struct is a software layout and its embedded struct pcie_tlp_log is larger than the on-wire AER capability. As a result the loop reads past the mapped AER register block. The over-read also populates the software-only tail fields including header_log.header_len. An out-of-range header_len passed to pcie_print_tlp_log() can then loop past the header log buffer and cause a second out-of-bounds read. The read was correct when introduced, but struct pcie_tlp_log has since grown (Header Log and TLP Prefix Log sizes, header_len and flit fields), so sizeof(struct aer_capability_regs) no longer matches the physical AER capability. Bound the read to the physical AER registers, header through the 16 byte Header Log. Zero the destination first so the software-only fields are deterministic. Fixes: 6ac07883dbb5 ("cxl/pci: Add RCH downstream port error logging") Reported-by: Sashiko <sashiko@linuxfoundation.org> Cc: stable@vger.kernel.org Signed-off-by: Terry Bowman <terry.bowman@amd.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260803221810.3685703-2-terry.bowman@amd.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>