From: Terry Bowman <terry.bowman@amd.com>
To: <dave@stgolabs.net>, <jonathan.cameron@huawei.com>,
<dave.jiang@intel.com>, <alison.schofield@intel.com>,
<dan.j.williams@intel.com>, <bhelgaas@google.com>,
<shiju.jose@huawei.com>, <ming.li@zohomail.com>,
<Smita.KoralahalliChannabasappa@amd.com>, <rrichter@amd.com>,
<dan.carpenter@linaro.org>, <PradeepVineshReddy.Kodamati@amd.com>,
<lukas@wunner.de>, <Benjamin.Cheatham@amd.com>,
<sathyanarayanan.kuppuswamy@linux.intel.com>,
<terry.bowman@amd.com>, <linux-cxl@vger.kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <linux-pci@vger.kernel.org>
Subject: [PATCH v10 15/17] CXL/PCI: Introduce CXL Port protocol error handlers
Date: Thu, 26 Jun 2025 17:42:50 -0500 [thread overview]
Message-ID: <20250626224252.1415009-16-terry.bowman@amd.com> (raw)
In-Reply-To: <20250626224252.1415009-1-terry.bowman@amd.com>
Introduce CXL error handlers for CXL Port devices.
Add functions cxl_port_cor_error_detected() and cxl_port_error_detected().
These will serve as the handlers for all CXL Port devices. Introduce
cxl_get_ras_base() to provide the RAS base address needed by the handlers.
Update cxl_handle_proto_error() to call the CXL Port or CXL Endpoint
handler depending on which CXL device reports the error.
Implement cxl_get_ras_base() to return the cached RAS register address of a
CXL Root Port, CXL Downstream Port, or CXL Upstream Port.
Introduce get_pci_cxl_host_dev() to return the host responsible for
releasing the RAS mapped resources. CXL endpoints do not use a host to
manage its resources, allow for NULL in the case of an EP. Use reference
count increment on the host to prevent resource release. Make the caller
responsible for the reference decrement.
Update the AER driver's is_cxl_error() to remove the filter PCI type check
because CXL Port devices are now supported.
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
drivers/cxl/core/core.h | 2 +
drivers/cxl/core/native_ras.c | 74 ++++++++++++++++++++++++++++++++---
drivers/cxl/core/pci.c | 60 ++++++++++++++++++++++++++++
drivers/cxl/core/port.c | 4 +-
drivers/cxl/cxl.h | 5 +++
drivers/pci/pcie/cxl_aer.c | 17 ++++----
6 files changed, 145 insertions(+), 17 deletions(-)
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 4c08bb92e2f9..f5a2571fc208 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -122,6 +122,8 @@ void cxl_ras_exit(void);
int cxl_gpf_port_setup(struct cxl_dport *dport);
int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
int nid, resource_size_t *size);
+struct cxl_port *find_cxl_port(struct device *dport_dev,
+ struct cxl_dport **dport);
#ifdef CONFIG_PCIEAER_CXL
void cxl_native_ras_init(void);
diff --git a/drivers/cxl/core/native_ras.c b/drivers/cxl/core/native_ras.c
index 89b65a35f2c0..c7f9a237a1a2 100644
--- a/drivers/cxl/core/native_ras.c
+++ b/drivers/cxl/core/native_ras.c
@@ -9,18 +9,74 @@
#include <cxlpci.h>
#include <core/core.h>
+int match_uport(struct device *dev, const void *data)
+{
+ const struct device *uport_dev = data;
+ struct cxl_port *port;
+
+ if (!is_cxl_port(dev))
+ return 0;
+
+ port = to_cxl_port(dev);
+
+ return port->uport_dev == uport_dev;
+}
+EXPORT_SYMBOL_NS_GPL(match_uport, "CXL");
+
+/*
+ * Return 'struct device *' responsible for freeing pdev's CXL resources.
+ * Caller is responsible for reference count decrementing the return
+ * 'struct device *'.
+ *
+ * pdev: CXL PCI device to find the host device.
+ */
+static struct device *get_pci_cxl_host_dev(struct pci_dev *pdev)
+{
+ switch (pci_pcie_type(pdev)) {
+ case PCI_EXP_TYPE_ROOT_PORT:
+ case PCI_EXP_TYPE_DOWNSTREAM:
+ {
+ struct cxl_dport *dport = NULL;
+ struct cxl_port *port = find_cxl_port(&pdev->dev, &dport);
+
+ if (!port)
+ return NULL;
+
+ return &port->dev;
+ }
+ case PCI_EXP_TYPE_UPSTREAM:
+ {
+ struct device *port_dev = bus_find_device(&cxl_bus_type, NULL,
+ &pdev->dev, match_uport);
+
+ if (!port_dev || !is_cxl_port(port_dev))
+ return NULL;
+
+ return port_dev;
+ }
+ /* Endpoint resources are managed by endpoint itself */
+ case PCI_EXP_TYPE_ENDPOINT:
+ case PCI_EXP_TYPE_RC_END:
+ return NULL;
+ }
+
+ pci_warn_once(pdev, "Error: Unsupported device type (%X)", pci_pcie_type(pdev));
+ return NULL;
+}
+
static int cxl_report_error_detected(struct pci_dev *pdev, void *data)
{
+ struct device *host_dev __free(put_device) = get_pci_cxl_host_dev(pdev);
pci_ers_result_t vote, *result = data;
struct device *dev = &pdev->dev;
- if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ENDPOINT) &&
- (pci_pcie_type(pdev) != PCI_EXP_TYPE_RC_END))
- return 0;
-
guard(device)(dev);
- vote = cxl_error_detected(dev);
+ if ((pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT) ||
+ (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END))
+ vote = cxl_error_detected(dev);
+ else
+ vote = cxl_port_error_detected(dev);
*result = merge_result(*result, vote);
return 0;
@@ -112,6 +168,7 @@ static void cxl_handle_proto_error(struct cxl_proto_error_info *err_info)
PCI_FUNC(err_info->devfn));
return;
}
+ struct device *host_dev __free(put_device) = get_pci_cxl_host_dev(pdev);
/*
* Internal errors of an RCEC indicate an AER error in an
@@ -122,6 +179,7 @@ static void cxl_handle_proto_error(struct cxl_proto_error_info *err_info)
return pcie_walk_rcec(pdev, cxl_rch_handle_error_iter, err_info);
if (err_info->severity == AER_CORRECTABLE) {
+ struct device *dev = &pdev->dev;
int aer = pdev->aer_cap;
if (aer)
@@ -129,7 +187,11 @@ static void cxl_handle_proto_error(struct cxl_proto_error_info *err_info)
aer + PCI_ERR_COR_STATUS,
0, PCI_ERR_COR_INTERNAL);
- cxl_cor_error_detected(&pdev->dev);
+ if ((pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT) ||
+ (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END))
+ cxl_cor_error_detected(dev);
+ else
+ cxl_port_cor_error_detected(dev);
pcie_clear_device_status(pdev);
} else {
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index 7209ffb5c2fe..7a83408ad0bb 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -743,6 +743,66 @@ static pci_ers_result_t cxl_handle_ras(struct device *dev, u64 serial,
#ifdef CONFIG_PCIEAER_CXL
+static void __iomem *cxl_get_ras_base(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ switch (pci_pcie_type(pdev)) {
+ case PCI_EXP_TYPE_ROOT_PORT:
+ case PCI_EXP_TYPE_DOWNSTREAM:
+ {
+ struct cxl_dport *dport = NULL;
+ struct cxl_port *port __free(put_cxl_port) = find_cxl_port(&pdev->dev, &dport);
+
+ if (!dport || !dport->dport_dev) {
+ pci_err(pdev, "Failed to find the CXL device");
+ return NULL;
+ }
+
+ if (!dport)
+ return NULL;
+
+ return dport->regs.ras;
+ }
+ case PCI_EXP_TYPE_UPSTREAM:
+ {
+ struct cxl_port *port;
+ struct device *dev __free(put_device) = bus_find_device(&cxl_bus_type, NULL,
+ &pdev->dev, match_uport);
+
+ if (!dev || !is_cxl_port(dev)) {
+ pci_err(pdev, "Failed to find the CXL device");
+ return NULL;
+ }
+
+ port = to_cxl_port(dev);
+ if (!port)
+ return NULL;
+
+ return port->uport_regs.ras;
+ }
+ }
+
+ pci_warn_once(pdev, "Error: Unsupported device type (%X)", pci_pcie_type(pdev));
+ return NULL;
+}
+
+void cxl_port_cor_error_detected(struct device *dev)
+{
+ void __iomem *ras_base = cxl_get_ras_base(dev);
+
+ cxl_handle_cor_ras(dev, 0, ras_base);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_port_cor_error_detected, "CXL");
+
+pci_ers_result_t cxl_port_error_detected(struct device *dev)
+{
+ void __iomem *ras_base = cxl_get_ras_base(dev);
+
+ return cxl_handle_ras(dev, 0, ras_base);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_port_error_detected, "CXL");
+
static void cxl_handle_rdport_cor_ras(struct cxl_dev_state *cxlds,
struct cxl_dport *dport)
{
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 8e8f21197c86..c76a1289e24e 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1341,8 +1341,8 @@ static struct cxl_port *__find_cxl_port(struct cxl_find_port_ctx *ctx)
return NULL;
}
-static struct cxl_port *find_cxl_port(struct device *dport_dev,
- struct cxl_dport **dport)
+struct cxl_port *find_cxl_port(struct device *dport_dev,
+ struct cxl_dport **dport)
{
struct cxl_find_port_ctx ctx = {
.dport_dev = dport_dev,
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index a2eedc8a82e8..19eb33a7de6a 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -801,6 +801,9 @@ int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint)
void cxl_cor_error_detected(struct device *dev);
pci_ers_result_t cxl_error_detected(struct device *dev);
+void cxl_port_cor_error_detected(struct device *dev);
+pci_ers_result_t cxl_port_error_detected(struct device *dev);
+
/**
* struct cxl_endpoint_dvsec_info - Cached DVSEC info
* @mem_enabled: cached value of mem_enabled in the DVSEC at init time
@@ -915,6 +918,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
+int match_uport(struct device *dev, const void *data);
+
/*
* Unit test builds overrides this to __weak, find the 'strong' version
* of these symbols in tools/testing/cxl/.
diff --git a/drivers/pci/pcie/cxl_aer.c b/drivers/pci/pcie/cxl_aer.c
index b238791b7101..38dc82df0baf 100644
--- a/drivers/pci/pcie/cxl_aer.c
+++ b/drivers/pci/pcie/cxl_aer.c
@@ -73,11 +73,6 @@ bool is_cxl_error(struct pci_dev *pdev, struct aer_err_info *info)
if (!info || !info->is_cxl)
return false;
- /* Only CXL Endpoints are currently supported */
- if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ENDPOINT) &&
- (pci_pcie_type(pdev) != PCI_EXP_TYPE_RC_EC))
- return false;
-
return is_internal_error(info);
}
@@ -92,13 +87,17 @@ static int handles_cxl_error_iter(struct pci_dev *dev, void *data)
return *handles_cxl;
}
-static bool handles_cxl_errors(struct pci_dev *rcec)
+static bool handles_cxl_errors(struct pci_dev *dev)
{
bool handles_cxl = false;
- if (pci_pcie_type(rcec) == PCI_EXP_TYPE_RC_EC &&
- pcie_aer_is_native(rcec))
- pcie_walk_rcec(rcec, handles_cxl_error_iter, &handles_cxl);
+ if (!pcie_aer_is_native(dev))
+ return false;
+
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC)
+ pcie_walk_rcec(dev, handles_cxl_error_iter, &handles_cxl);
+ else
+ handles_cxl = pcie_is_cxl(dev);
return handles_cxl;
}
--
2.34.1
next prev parent reply other threads:[~2025-06-26 22:45 UTC|newest]
Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-26 22:42 [PATCH v10 00/17] Enable CXL PCIe Port Protocol Error handling and logging Terry Bowman
2025-06-26 22:42 ` [PATCH v10 01/17] cxl/pci: Remove unnecessary CXL Endpoint handling helper functions Terry Bowman
2025-07-18 17:55 ` Dave Jiang
2025-07-23 21:58 ` dan.j.williams
2025-07-23 22:15 ` Dave Jiang
2025-06-26 22:42 ` [PATCH v10 02/17] PCI/CXL: Add pcie_is_cxl() Terry Bowman
2025-07-23 22:30 ` dan.j.williams
2025-08-09 10:56 ` Alejandro Lucero Palau
2025-08-11 19:14 ` Bowman, Terry
2025-08-11 23:14 ` dan.j.williams
2025-06-26 22:42 ` [PATCH v10 03/17] PCI/AER: Report CXL or PCIe bus error type in trace logging Terry Bowman
2025-06-26 23:25 ` Sathyanarayanan Kuppuswamy
2025-06-27 9:53 ` Jonathan Cameron
2025-07-02 16:00 ` Bowman, Terry
2025-06-27 11:32 ` Shiju Jose
2025-07-01 21:27 ` Dave Jiang
2025-07-23 22:56 ` dan.j.williams
2025-06-26 22:42 ` [PATCH v10 04/17] CXL/AER: Introduce CXL specific AER driver file Terry Bowman
2025-06-26 23:42 ` Sathyanarayanan Kuppuswamy
2025-06-27 10:12 ` Jonathan Cameron
2025-06-27 14:29 ` Bowman, Terry
2025-07-24 0:01 ` dan.j.williams
2025-07-24 17:06 ` Bowman, Terry
2025-07-24 20:32 ` dan.j.williams
2025-07-24 1:16 ` dan.j.williams
2025-07-24 17:02 ` Bowman, Terry
2025-07-24 20:23 ` dan.j.williams
2025-06-26 22:42 ` [PATCH v10 05/17] CXL/AER: Introduce kfifo for forwarding CXL errors Terry Bowman
2025-06-27 10:24 ` Jonathan Cameron
2025-07-02 16:21 ` Bowman, Terry
2025-07-02 19:54 ` Dan Carpenter
2025-07-02 19:57 ` Bowman, Terry
2025-07-03 10:06 ` Jonathan Cameron
2025-07-01 21:53 ` Dave Jiang
2025-07-02 17:10 ` Bowman, Terry
2025-07-24 2:01 ` dan.j.williams
2025-07-24 17:21 ` Bowman, Terry
2025-07-24 20:55 ` dan.j.williams
2025-06-26 22:42 ` [PATCH v10 06/17] PCI/AER: Dequeue forwarded CXL error Terry Bowman
2025-06-27 11:00 ` Jonathan Cameron
2025-07-02 17:51 ` Bowman, Terry
2025-07-01 23:04 ` Dave Jiang
2025-07-02 17:56 ` Bowman, Terry
2025-07-03 10:11 ` Jonathan Cameron
2025-07-25 0:38 ` dan.j.williams
2025-06-26 22:42 ` [PATCH v10 07/17] CXL/PCI: Introduce CXL uncorrectable protocol error recovery Terry Bowman
2025-06-27 11:05 ` Jonathan Cameron
2025-07-02 21:06 ` Bowman, Terry
2025-06-27 12:27 ` Shiju Jose
2025-07-02 21:34 ` Bowman, Terry
2025-06-26 22:42 ` [PATCH v10 08/17] cxl/pci: Move RAS initialization to cxl_port driver Terry Bowman
2025-06-27 11:12 ` Jonathan Cameron
2025-07-18 18:01 ` Dave Jiang
2025-06-26 22:42 ` [PATCH v10 09/17] cxl/pci: Map CXL Endpoint Port and CXL Switch Port RAS registers Terry Bowman
2025-06-27 11:17 ` Jonathan Cameron
2025-07-02 21:41 ` Bowman, Terry
2025-07-18 21:28 ` Dave Jiang
2025-07-18 21:55 ` Bowman, Terry
2025-07-18 22:01 ` Dave Jiang
2025-07-18 22:40 ` Bowman, Terry
2025-07-18 22:45 ` Dave Jiang
2025-06-26 22:42 ` [PATCH v10 10/17] cxl/pci: Update RAS handler interfaces to also support CXL Ports Terry Bowman
2025-06-26 22:42 ` [PATCH v10 11/17] cxl/pci: Log message if RAS registers are unmapped Terry Bowman
2025-07-21 21:56 ` Dave Jiang
2025-06-26 22:42 ` [PATCH v10 12/17] cxl/pci: Unify CXL trace logging for CXL Endpoints and CXL Ports Terry Bowman
2025-06-27 12:22 ` Shiju Jose
2025-07-02 1:18 ` Alison Schofield
2025-07-02 22:07 ` Bowman, Terry
2025-07-02 21:56 ` Bowman, Terry
2025-06-26 22:42 ` [PATCH v10 13/17] cxl/pci: Update cxl_handle_cor_ras() to return early if no RAS errors Terry Bowman
2025-06-27 11:48 ` Jonathan Cameron
2025-07-21 22:17 ` Dave Jiang
2025-06-26 22:42 ` [PATCH v10 14/17] cxl/pci: Introduce CXL Endpoint protocol error handlers Terry Bowman
2025-06-27 11:52 ` Jonathan Cameron
2025-06-27 12:27 ` Shiju Jose
2025-07-21 22:35 ` Dave Jiang
2025-07-22 18:23 ` Bowman, Terry
2025-06-26 22:42 ` Terry Bowman [this message]
2025-06-26 22:42 ` [PATCH v10 16/17] CXL/PCI: Enable CXL protocol errors during CXL Port probe Terry Bowman
2025-06-26 22:42 ` [PATCH v10 17/17] CXL/PCI: Disable CXL protocol error interrupts during CXL Port cleanup Terry Bowman
2025-07-23 21:55 ` [PATCH v10 00/17] Enable CXL PCIe Port Protocol Error handling and logging dan.j.williams
2025-08-18 15:18 ` Joshua Hahn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250626224252.1415009-16-terry.bowman@amd.com \
--to=terry.bowman@amd.com \
--cc=Benjamin.Cheatham@amd.com \
--cc=PradeepVineshReddy.Kodamati@amd.com \
--cc=Smita.KoralahalliChannabasappa@amd.com \
--cc=alison.schofield@intel.com \
--cc=bhelgaas@google.com \
--cc=dan.carpenter@linaro.org \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=jonathan.cameron@huawei.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lukas@wunner.de \
--cc=ming.li@zohomail.com \
--cc=rrichter@amd.com \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=shiju.jose@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®