mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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>,
	<linux-cxl@vger.kernel.org>, <alucerop@amd.com>,
	<ira.weiny@intel.com>
Cc: <linux-kernel@vger.kernel.org>, <linux-pci@vger.kernel.org>
Subject: [PATCH v11 19/23] CXL/PCI: Introduce CXL Port protocol error handlers
Date: Tue, 26 Aug 2025 20:35:34 -0500	[thread overview]
Message-ID: <20250827013539.903682-20-terry.bowman@amd.com> (raw)
In-Reply-To: <20250827013539.903682-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() 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>

---
Changes in v10->v11:
- None
---
 drivers/cxl/core/core.h    |   9 ++
 drivers/cxl/core/port.c    |   4 +-
 drivers/cxl/core/ras.c     | 176 +++++++++++++++++++++++++++++++++++--
 drivers/pci/pcie/cxl_aer.c |   5 +-
 4 files changed, 186 insertions(+), 8 deletions(-)

diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 6e3e7f2e0e2d..7e66fbb07b8a 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -155,6 +155,8 @@ pci_ers_result_t pci_error_detected(struct pci_dev *pdev,
 void pci_cor_error_detected(struct pci_dev *pdev);
 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);
 #else
 static inline int cxl_ras_init(void)
 {
@@ -179,9 +181,16 @@ static inline pci_ers_result_t cxl_error_detected(struct device *dev)
 {
 	return PCI_ERS_RESULT_NONE;
 }
+static inline void cxl_port_cor_error_detected(struct device *dev) { }
+static inline pci_ers_result_t cxl_port_error_detected(struct device *dev)
+{
+	return PCI_ERS_RESULT_NONE;
+}
 #endif // CONFIG_CXL_RAS
 
 int cxl_gpf_port_setup(struct cxl_dport *dport);
+struct cxl_port *find_cxl_port(struct device *dport_dev,
+			       struct cxl_dport **dport);
 
 #ifdef CONFIG_CXL_FEATURES
 struct cxl_feat_entry *
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 29197376b18e..758fb73374c1 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1335,8 +1335,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/core/ras.c b/drivers/cxl/core/ras.c
index a2e95c49f965..536ca9c815ce 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -251,6 +251,154 @@ static void cxl_dport_map_ras(struct cxl_dport *dport)
 		dev_dbg(dev, "Failed to map RAS capability.\n");
 }
 
+static 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;
+}
+
+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 *port_dev __free(put_device) =
+			bus_find_device(&cxl_bus_type, NULL,
+					&pdev->dev, match_uport);
+
+		if (!port_dev || !is_cxl_port(port_dev)) {
+			pci_err(pdev, "Failed to find the CXL device");
+			return NULL;
+		}
+
+		port = to_cxl_port(port_dev);
+		if (!port)
+			return NULL;
+
+		return port->uport_regs.ras;
+	}
+	}
+
+	dev_warn_once(dev, "Error: Unsupported device type (%X)", pci_pcie_type(pdev));
+	return NULL;
+}
+
+static struct device *pci_to_cxl_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 __free(put_cxl_port) =
+			find_cxl_port(&pdev->dev, &dport);
+
+		if (!dport) {
+			pci_err(pdev, "Failed to find the CXL device");
+			return NULL;
+		}
+
+		return dport->dport_dev;
+	}
+	case PCI_EXP_TYPE_UPSTREAM:
+	{
+		struct cxl_port *port;
+		struct device *port_dev __free(put_device) =
+			bus_find_device(&cxl_bus_type, NULL,
+					&pdev->dev, match_uport);
+
+		if (!port_dev || !is_cxl_port(port_dev)) {
+			pci_err(pdev, "Failed to find the CXL device");
+			return NULL;
+		}
+
+		port = to_cxl_port(port_dev);
+		if (!port)
+			return NULL;
+
+		return port->uport_dev;
+	}
+	case PCI_EXP_TYPE_ENDPOINT:
+	{
+		struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
+
+		return cxlds->dev;
+	}
+	}
+
+	pci_warn_once(pdev, "Error: Unsupported device type (%X)", pci_pcie_type(pdev));
+	return NULL;
+}
+
+
+/*
+ * Return 'struct device *' responsible for freeing pdev's CXL resources.
+ * Caller is responsible for reference count decrementing the return
+ * 'struct device *'.
+ *
+ * dev: Find the host of this dev
+ */
+static struct device *get_cxl_host_dev(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 = 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:
+		return NULL;
+	}
+
+	dev_warn_once(dev, "Error: Unsupported device type (%X)", pci_pcie_type(pdev));
+	return NULL;
+}
+
 /**
  * cxl_dport_init_ras_reporting - Setup CXL RAS report on this dport
  * @dport: the cxl_dport that needs to be initialized
@@ -399,6 +547,22 @@ static pci_ers_result_t cxl_handle_ras(struct device *dev, u64 serial, void __io
 	return PCI_ERS_RESULT_PANIC;
 }
 
+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");
+
 void cxl_cor_error_detected(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -469,9 +633,8 @@ EXPORT_SYMBOL_NS_GPL(pci_error_detected, "CXL");
 static void cxl_handle_proto_error(struct cxl_proto_err_work_data *err_info)
 {
 	struct pci_dev *pdev = err_info->pdev;
-	struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
-	struct cxl_memdev *cxlmd = cxlds->cxlmd;
-	struct device *host_dev __free(put_device) = get_device(&cxlmd->dev);
+	struct device *dev = pci_to_cxl_dev(pdev);
+	struct device *host_dev __free(put_device) = get_cxl_host_dev(&pdev->dev);
 
 	if (err_info->severity == AER_CORRECTABLE) {
 		int aer = pdev->aer_cap;
@@ -481,11 +644,14 @@ static void cxl_handle_proto_error(struct cxl_proto_err_work_data *err_info)
 						       aer + PCI_ERR_COR_STATUS,
 						       0, PCI_ERR_COR_INTERNAL);
 
-		cxl_cor_error_detected(&cxlmd->dev);
+		if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT)
+			cxl_error_detected(&pdev->dev);
+		else
+			cxl_port_cor_error_detected(dev);
 
 		pcie_clear_device_status(pdev);
 	} else {
-		cxl_do_recovery(&cxlmd->dev);
+		cxl_do_recovery(dev);
 	}
 }
 
diff --git a/drivers/pci/pcie/cxl_aer.c b/drivers/pci/pcie/cxl_aer.c
index 74e6d2d04ab6..6eeff0b78b47 100644
--- a/drivers/pci/pcie/cxl_aer.c
+++ b/drivers/pci/pcie/cxl_aer.c
@@ -68,7 +68,10 @@ bool is_cxl_error(struct pci_dev *pdev, struct aer_err_info *info)
 	if (!info || !info->is_cxl)
 		return false;
 
-	if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ENDPOINT)
+	if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ENDPOINT) &&
+	    (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) &&
+	    (pci_pcie_type(pdev) != PCI_EXP_TYPE_UPSTREAM) &&
+	    (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM))
 		return false;
 
 	return is_internal_error(info);
-- 
2.51.0.rc2.21.ge5ab6b3e5a


  parent reply	other threads:[~2025-08-27  1:39 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-27  1:35 [PATCH v11 00/23] Enable CXL PCIe Port Protocol Error handling and logging Terry Bowman
2025-08-27  1:35 ` [PATCH v11 01/23] cxl: Remove ifdef blocks of CONFIG_PCIEAER_CXL from core/pci.c Terry Bowman
2025-08-27  1:35 ` [PATCH v11 02/23] CXL/AER: Remove CONFIG_PCIEAER_CXL and replace with CONFIG_CXL_RAS Terry Bowman
2025-08-29 15:24   ` Jonathan Cameron
2025-08-29 18:16   ` Sathyanarayanan Kuppuswamy
2025-08-27  1:35 ` [PATCH v11 03/23] cxl/pci: Remove unnecessary CXL Endpoint handling helper functions Terry Bowman
2025-08-28 15:28   ` Dave Jiang
2025-08-27  1:35 ` [PATCH v11 04/23] cxl/pci: Remove unnecessary CXL RCH " Terry Bowman
2025-08-28  8:35   ` Alejandro Lucero Palau
2025-08-28 17:32   ` Dave Jiang
2025-08-27  1:35 ` [PATCH v11 05/23] cxl: Move CXL driver RCH error handling into CONFIG_CXL_RCH_RAS conditional block Terry Bowman
2025-08-28  8:57   ` Alejandro Lucero Palau
2025-09-10 16:43     ` Bowman, Terry
2025-08-29 15:33   ` Jonathan Cameron
2025-09-11 17:48     ` Bowman, Terry
2025-09-11 19:41       ` Dave Jiang
2025-09-15 13:32         ` Bowman, Terry
2025-08-27  1:35 ` [PATCH v11 06/23] CXL/AER: Introduce rch_aer.c into AER driver for handling CXL RCH errors Terry Bowman
2025-08-28 20:53   ` Dave Jiang
2025-08-29  8:39     ` Lukas Wunner
2025-09-10 17:01       ` Bowman, Terry
2025-09-10 17:26         ` Dave Jiang
2025-09-12 13:59       ` Bowman, Terry
2025-09-12 19:09         ` Lukas Wunner
2025-09-10 16:56     ` Bowman, Terry
2025-09-10 12:43   ` Jonathan Cameron
2025-08-27  1:35 ` [PATCH v11 07/23] CXL/PCI: Move CXL DVSEC definitions into uapi/linux/pci_regs.h Terry Bowman
2025-08-27 14:51   ` Lukas Wunner
2025-08-29 15:42     ` Jonathan Cameron
2025-08-29 15:47     ` Jonathan Cameron
2025-08-28 21:07   ` Dave Jiang
2025-09-10 18:11     ` Bowman, Terry
2025-09-10 20:06       ` Dave Jiang
2025-08-27  1:35 ` [PATCH v11 08/23] PCI/CXL: Introduce pcie_is_cxl() Terry Bowman
2025-08-28  8:18   ` Alejandro Lucero Palau
2025-09-10 16:24     ` Bowman, Terry
2025-09-11  3:48       ` Lukas Wunner
2025-09-10 13:10   ` Jonathan Cameron
2025-08-27  1:35 ` [PATCH v11 09/23] PCI/AER: Report CXL or PCIe bus error type in trace logging Terry Bowman
2025-08-27  7:37   ` Lukas Wunner
2025-09-10 15:26     ` Bowman, Terry
2025-09-10 15:33       ` Lukas Wunner
2025-09-11  5:07   ` Lukas Wunner
2025-08-27  1:35 ` [PATCH v11 10/23] CXL/AER: Update PCI class code check to use FIELD_GET() Terry Bowman
2025-08-29 16:03   ` Jonathan Cameron
2025-09-11 18:18     ` Bowman, Terry
2025-08-27  1:35 ` [PATCH v11 11/23] cxl/pci: Update RAS handler interfaces to also support CXL Ports Terry Bowman
2025-08-27  1:35 ` [PATCH v11 12/23] cxl/pci: Log message if RAS registers are unmapped Terry Bowman
2025-08-27  1:35 ` [PATCH v11 13/23] cxl/pci: Unify CXL trace logging for CXL Endpoints and CXL Ports Terry Bowman
2025-08-27 11:55   ` Shiju Jose
2025-08-29 16:06     ` Jonathan Cameron
2025-08-27  1:35 ` [PATCH v11 14/23] cxl/pci: Update cxl_handle_cor_ras() to return early if no RAS errors Terry Bowman
2025-08-27  1:35 ` [PATCH v11 15/23] cxl/pci: Map CXL Endpoint Port and CXL Switch Port RAS registers Terry Bowman
2025-08-28 23:05   ` Dave Jiang
2025-09-10 18:40     ` Bowman, Terry
2025-08-27  1:35 ` [PATCH v11 16/23] cxl/pci: Introduce CXL Endpoint protocol error handlers Terry Bowman
2025-08-27  7:48   ` Lukas Wunner
2025-09-10 13:23   ` Jonathan Cameron
2025-08-27  1:35 ` [PATCH v11 17/23] CXL/AER: Introduce cxl_aer.c into AER driver for forwarding CXL errors Terry Bowman
2025-08-27  7:56   ` Lukas Wunner
2025-08-27  1:35 ` [PATCH v11 18/23] PCI/AER: Dequeue forwarded CXL error Terry Bowman
2025-08-29  0:43   ` Dave Jiang
2025-08-29  7:10     ` Lukas Wunner
2025-09-16 15:18       ` Bowman, Terry
2025-09-11 14:33     ` Bowman, Terry
2025-09-11 15:41       ` Dave Jiang
2025-09-11 16:47         ` Bowman, Terry
2025-09-11 19:45           ` Dave Jiang
2025-09-10 13:29   ` Jonathan Cameron
2025-08-27  1:35 ` Terry Bowman [this message]
2025-08-30  0:17   ` [PATCH v11 19/23] CXL/PCI: Introduce CXL Port protocol error handlers Dave Jiang
2025-08-27  1:35 ` [PATCH v11 20/23] CXL/PCI: Export and rename merge_result() to pci_ers_merge_result() Terry Bowman
2025-08-27  8:04   ` Lukas Wunner
2025-09-10 15:57     ` Bowman, Terry
2025-09-11  3:44       ` Lukas Wunner
2025-08-27 12:19   ` kernel test robot
2025-08-27  1:35 ` [PATCH v11 21/23] CXL/PCI: Introduce CXL uncorrectable protocol error recovery Terry Bowman
2025-09-03 22:30   ` Dave Jiang
2025-09-11 19:19     ` Bowman, Terry
2025-09-11 19:48       ` Dave Jiang
2025-09-10 13:33   ` Jonathan Cameron
2025-08-27  1:35 ` [PATCH v11 22/23] CXL/PCI: Enable CXL protocol errors during CXL Port probe Terry Bowman
2025-09-03 23:23   ` Dave Jiang
2025-08-27  1:35 ` [PATCH v11 23/23] CXL/PCI: Disable CXL protocol error interrupts during CXL Port cleanup Terry Bowman
2025-09-10 15:07   ` Gregory Price
2025-09-11 20:19     ` Bowman, Terry
2025-08-29  0:07 ` [PATCH v11 00/23] Enable CXL PCIe Port Protocol Error handling and logging Dave Jiang
2025-09-23  3:29 ` Gregory Price
2025-09-23  9:21   ` Srinivasulu Thanneeru

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=20250827013539.903682-20-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=alucerop@amd.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=ira.weiny@intel.com \
    --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®