CXL Endpoint (EP) Ports may include Root Ports (RP) or Downstream Switch
Ports (DSP). CXL RPs and DSPs contain RAS registers that require memory
mapping to enable RAS logging. This initialization is currently missing and
must be added for CXL RPs and DSPs.
Update cxl_dport_init_ras_reporting() to support RP and DSP RAS mapping.
Add alongside the existing Restricted CXL Host Downstream Port RAS mapping.
Update cxl_endpoint_port_probe() to invoke cxl_dport_init_ras_reporting().
This will initiate the RAS mapping for CXL RPs and DSPs when each CXL EP is
created and added to the EP port.
Make a call to cxl_port_setup_regs() in cxl_port_add(). This will probe the
Upstream Port's CXL capabilities' physical location to be used in mapping
the RAS registers.
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
---
Changes in v12->v13:
- Change as result of dport delay fix. No longer need switchport and
endport approach. (Terry)
Changes in v11->v12:
- Add check for dport_parent->rch before calling cxl_dport_init_ras_reporting().
RCH dports are initialized from cxl_dport_init_ras_reporting cxl_mem_probe().
Changes in v10->v11:
- Use local pointer for readability in cxl_switch_port_init_ras() (Jonathan Cameron)
- Rename port to be ep in cxl_endpoint_port_init_ras() (Dave Jiang)
- Rename dport to be parent_dport in cxl_endpoint_port_init_ras()
and cxl_switch_port_init_ras() (Dave Jiang)
- Port helper changes were in cxl/port.c, now in core/ras.c (Dave Jiang)
---
drivers/cxl/core/port.c | 4 ++++
drivers/cxl/core/ras.c | 12 ++++++++++++
drivers/cxl/cxl.h | 2 ++
drivers/cxl/cxlpci.h | 4 ++++
drivers/cxl/mem.c | 3 ++-
5 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 8128fd2b5b31..48f6a1492544 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1194,6 +1194,8 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
return ERR_PTR(rc);
}
port->component_reg_phys = CXL_RESOURCE_NONE;
+ if (!is_cxl_endpoint(port) && dev_is_pci(port->uport_dev))
+ cxl_uport_init_ras_reporting(port, &port->dev);
}
get_device(dport_dev);
@@ -1623,6 +1625,8 @@ static struct cxl_dport *cxl_port_add_dport(struct cxl_port *port,
cxl_switch_parse_cdat(new_dport);
+ cxl_dport_init_ras_reporting(new_dport, &port->dev);
+
if (ida_is_empty(&port->decoder_ida)) {
rc = devm_cxl_switch_port_decoders_setup(port);
if (rc)
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index 246dfe56617a..19d9ffe885bf 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -162,6 +162,18 @@ void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
}
EXPORT_SYMBOL_NS_GPL(cxl_dport_init_ras_reporting, "CXL");
+void cxl_uport_init_ras_reporting(struct cxl_port *port,
+ struct device *host)
+{
+ struct cxl_register_map *map = &port->reg_map;
+
+ map->host = host;
+ if (cxl_map_component_regs(map, &port->uport_regs,
+ BIT(CXL_CM_CAP_CAP_ID_RAS)))
+ dev_dbg(&port->dev, "Failed to map RAS capability\n");
+}
+EXPORT_SYMBOL_NS_GPL(cxl_uport_init_ras_reporting, "CXL");
+
void cxl_handle_cor_ras(struct device *dev, u64 serial, void __iomem *ras_base)
{
void __iomem *addr;
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 259ed4b676e1..b7654d40dc9e 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -599,6 +599,7 @@ struct cxl_dax_region {
* @parent_dport: dport that points to this port in the parent
* @decoder_ida: allocator for decoder ids
* @reg_map: component and ras register mapping parameters
+ * @uport_regs: mapped component registers
* @nr_dports: number of entries in @dports
* @hdm_end: track last allocated HDM decoder instance for allocation ordering
* @commit_end: cursor to track highest committed decoder for commit ordering
@@ -620,6 +621,7 @@ struct cxl_port {
struct cxl_dport *parent_dport;
struct ida decoder_ida;
struct cxl_register_map reg_map;
+ struct cxl_component_regs uport_regs;
int nr_dports;
int hdm_end;
int commit_end;
diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
index 0c8b6ee7b6de..a0a491e7b5b9 100644
--- a/drivers/cxl/cxlpci.h
+++ b/drivers/cxl/cxlpci.h
@@ -83,6 +83,8 @@ void cxl_cor_error_detected(struct pci_dev *pdev);
pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
pci_channel_state_t state);
void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host);
+void cxl_uport_init_ras_reporting(struct cxl_port *port,
+ struct device *host);
#else
static inline void cxl_cor_error_detected(struct pci_dev *pdev) { }
@@ -94,6 +96,8 @@ static inline pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
static inline void cxl_dport_init_ras_reporting(struct cxl_dport *dport,
struct device *host) { }
+static inline void cxl_uport_init_ras_reporting(struct cxl_port *port,
+ struct device *host) { }
#endif
#endif /* __CXL_PCI_H__ */
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index 6e6777b7bafb..d2155f45240d 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -166,7 +166,8 @@ static int cxl_mem_probe(struct device *dev)
else
endpoint_parent = &parent_port->dev;
- cxl_dport_init_ras_reporting(dport, dev);
+ if (dport->rch)
+ cxl_dport_init_ras_reporting(dport, dev);
scoped_guard(device, endpoint_parent) {
if (!endpoint_parent->driver) {
--
2.34.1
On Tue, Nov 04, 2025 at 11:02:54AM -0600, Terry Bowman wrote:
> CXL Endpoint (EP) Ports may include Root Ports (RP) or Downstream Switch
> Ports (DSP). CXL RPs and DSPs contain RAS registers that require memory
> mapping to enable RAS logging. This initialization is currently missing and
> must be added for CXL RPs and DSPs.
>
> Update cxl_dport_init_ras_reporting() to support RP and DSP RAS mapping.
> Add alongside the existing Restricted CXL Host Downstream Port RAS mapping.
>
> Update cxl_endpoint_port_probe() to invoke cxl_dport_init_ras_reporting().
> This will initiate the RAS mapping for CXL RPs and DSPs when each CXL EP is
> created and added to the EP port.
>
> Make a call to cxl_port_setup_regs() in cxl_port_add(). This will probe the
> Upstream Port's CXL capabilities' physical location to be used in mapping
> the RAS registers.
>
> Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Terry,
This patch needed some cxl-test support:
Attaching what is needed to 'Make cxl_*_init_ras_reporting() work
with cxl-test"
It adds a mock version of cxl_uport_init_ras_reporting(), simply
following what existed for cxl_dport_init_ras_reporting().
The other changes apply a method that avoids circular dependencies
that the above patch introduced: cxl_mock->cxl_core->cxl_mock.
This method is a Dan invention that DaveJ first applied it here:
d96eb90d9ca6 ("cxl/test: Add mock version of devm_cxl_add_dport_by_dev()")
In my tree, I inserted and tested this after this patch I'm replying
to, but I think you'll need to combine them, or split some other way
so no patch introduces breakage.
--Alison
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
---
drivers/cxl/core/port.c | 4 ++--
drivers/cxl/core/ras.c | 12 ++++++------
drivers/cxl/cxl.h | 5 +++++
drivers/cxl/cxlpci.h | 6 ++++--
drivers/cxl/mem.c | 2 +-
tools/testing/cxl/Kbuild | 1 -
tools/testing/cxl/cxl_core_exports.c | 19 +++++++++++++++++++
tools/testing/cxl/exports.h | 8 ++++++++
tools/testing/cxl/test/mock.c | 25 +++++++++++++++++++++++--
9 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 48f6a1492544..f0fc917f9575 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1195,7 +1195,7 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
}
port->component_reg_phys = CXL_RESOURCE_NONE;
if (!is_cxl_endpoint(port) && dev_is_pci(port->uport_dev))
- cxl_uport_init_ras_reporting(port, &port->dev);
+ __cxl_uport_init_ras_reporting(port, &port->dev);
}
get_device(dport_dev);
@@ -1625,7 +1625,7 @@ static struct cxl_dport *cxl_port_add_dport(struct cxl_port *port,
cxl_switch_parse_cdat(new_dport);
- cxl_dport_init_ras_reporting(new_dport, &port->dev);
+ __cxl_dport_init_ras_reporting(new_dport, &port->dev);
if (ida_is_empty(&port->decoder_ida)) {
rc = devm_cxl_switch_port_decoders_setup(port);
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index 19d9ffe885bf..90bfb32cc3c5 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -141,11 +141,12 @@ static void cxl_dport_map_ras(struct cxl_dport *dport)
}
/**
- * cxl_dport_init_ras_reporting - Setup CXL RAS report on this dport
+ * __cxl_dport_init_ras_reporting - Setup CXL RAS report on this dport
* @dport: the cxl_dport that needs to be initialized
* @host: host device for devm operations
*/
-void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
+void __cxl_dport_init_ras_reporting(struct cxl_dport *dport,
+ struct device *host)
{
dport->reg_map.host = host;
cxl_dport_map_ras(dport);
@@ -160,10 +161,9 @@ void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
cxl_disable_rch_root_ints(dport);
}
}
-EXPORT_SYMBOL_NS_GPL(cxl_dport_init_ras_reporting, "CXL");
+EXPORT_SYMBOL_NS_GPL(__cxl_dport_init_ras_reporting, "CXL");
-void cxl_uport_init_ras_reporting(struct cxl_port *port,
- struct device *host)
+void __cxl_uport_init_ras_reporting(struct cxl_port *port, struct device *host)
{
struct cxl_register_map *map = &port->reg_map;
@@ -172,7 +172,7 @@ void cxl_uport_init_ras_reporting(struct cxl_port *port,
BIT(CXL_CM_CAP_CAP_ID_RAS)))
dev_dbg(&port->dev, "Failed to map RAS capability\n");
}
-EXPORT_SYMBOL_NS_GPL(cxl_uport_init_ras_reporting, "CXL");
+EXPORT_SYMBOL_NS_GPL(__cxl_uport_init_ras_reporting, "CXL");
void cxl_handle_cor_ras(struct device *dev, u64 serial, void __iomem *ras_base)
{
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index b7654d40dc9e..995e20a88d96 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -940,6 +940,11 @@ u16 cxl_gpf_get_dvsec(struct device *dev);
#define DECLARE_TESTABLE(x) __##x
#define devm_cxl_add_dport_by_dev DECLARE_TESTABLE(devm_cxl_add_dport_by_dev)
#define devm_cxl_switch_port_decoders_setup DECLARE_TESTABLE(devm_cxl_switch_port_decoders_setup)
+#define cxl_dport_init_ras_reporting \
+ DECLARE_TESTABLE(cxl_dport_init_ras_reporting)
+#define cxl_uport_init_ras_reporting \
+ DECLARE_TESTABLE(cxl_uport_init_ras_reporting)
+
#endif
#endif /* __CXL_H__ */
diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
index a0a491e7b5b9..846cf0935252 100644
--- a/drivers/cxl/cxlpci.h
+++ b/drivers/cxl/cxlpci.h
@@ -82,9 +82,11 @@ void read_cdat_data(struct cxl_port *port);
void cxl_cor_error_detected(struct pci_dev *pdev);
pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
pci_channel_state_t state);
+void __cxl_dport_init_ras_reporting(struct cxl_dport *dport,
+ struct device *host);
void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host);
-void cxl_uport_init_ras_reporting(struct cxl_port *port,
- struct device *host);
+void __cxl_uport_init_ras_reporting(struct cxl_port *port, struct device *host);
+void cxl_uport_init_ras_reporting(struct cxl_port *port, struct device *host);
#else
static inline void cxl_cor_error_detected(struct pci_dev *pdev) { }
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index d2155f45240d..782fdb552865 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -167,7 +167,7 @@ static int cxl_mem_probe(struct device *dev)
endpoint_parent = &parent_port->dev;
if (dport->rch)
- cxl_dport_init_ras_reporting(dport, dev);
+ __cxl_dport_init_ras_reporting(dport, dev);
scoped_guard(device, endpoint_parent) {
if (!endpoint_parent->driver) {
diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild
index 6905f8e710ab..fe80a811fdef 100644
--- a/tools/testing/cxl/Kbuild
+++ b/tools/testing/cxl/Kbuild
@@ -9,7 +9,6 @@ ldflags-y += --wrap=cxl_await_media_ready
ldflags-y += --wrap=devm_cxl_add_rch_dport
ldflags-y += --wrap=cxl_rcd_component_reg_phys
ldflags-y += --wrap=cxl_endpoint_parse_cdat
-ldflags-y += --wrap=cxl_dport_init_ras_reporting
ldflags-y += --wrap=devm_cxl_endpoint_decoders_setup
DRIVERS := ../../../drivers
diff --git a/tools/testing/cxl/cxl_core_exports.c b/tools/testing/cxl/cxl_core_exports.c
index 6754de35598d..5a071afa46fd 100644
--- a/tools/testing/cxl/cxl_core_exports.c
+++ b/tools/testing/cxl/cxl_core_exports.c
@@ -3,6 +3,7 @@
#include "cxl.h"
#include "exports.h"
+#include "cxlpci.h"
/* Exporting of cxl_core symbols that are only used by cxl_test */
EXPORT_SYMBOL_NS_GPL(cxl_num_decoders_committed, "CXL");
@@ -27,3 +28,21 @@ int devm_cxl_switch_port_decoders_setup(struct cxl_port *port)
return _devm_cxl_switch_port_decoders_setup(port);
}
EXPORT_SYMBOL_NS_GPL(devm_cxl_switch_port_decoders_setup, "CXL");
+
+cxl_dport_init_ras_reporting_fn _cxl_dport_init_ras_reporting =
+ __cxl_dport_init_ras_reporting;
+EXPORT_SYMBOL_NS_GPL(_cxl_dport_init_ras_reporting, "CXL");
+
+void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
+{
+ return _cxl_dport_init_ras_reporting(dport, host);
+}
+
+cxl_uport_init_ras_reporting_fn _cxl_uport_init_ras_reporting =
+ __cxl_uport_init_ras_reporting;
+EXPORT_SYMBOL_NS_GPL(_cxl_uport_init_ras_reporting, "CXL");
+
+void cxl_uport_init_ras_reporting(struct cxl_port *port, struct device *host)
+{
+ return _cxl_uport_init_ras_reporting(port, host);
+}
diff --git a/tools/testing/cxl/exports.h b/tools/testing/cxl/exports.h
index 7ebee7c0bd67..f3bcba8bc11b 100644
--- a/tools/testing/cxl/exports.h
+++ b/tools/testing/cxl/exports.h
@@ -10,4 +10,12 @@ extern cxl_add_dport_by_dev_fn _devm_cxl_add_dport_by_dev;
typedef int(*cxl_switch_decoders_setup_fn)(struct cxl_port *port);
extern cxl_switch_decoders_setup_fn _devm_cxl_switch_port_decoders_setup;
+typedef void (*cxl_dport_init_ras_reporting_fn)(struct cxl_dport *dport,
+ struct device *host);
+extern cxl_dport_init_ras_reporting_fn _cxl_dport_init_ras_reporting;
+
+typedef void (*cxl_uport_init_ras_reporting_fn)(struct cxl_port *port,
+ struct device *host);
+extern cxl_uport_init_ras_reporting_fn _cxl_uport_init_ras_reporting;
+
#endif
diff --git a/tools/testing/cxl/test/mock.c b/tools/testing/cxl/test/mock.c
index 995269a75cbd..776b951aab1a 100644
--- a/tools/testing/cxl/test/mock.c
+++ b/tools/testing/cxl/test/mock.c
@@ -18,6 +18,10 @@ static struct cxl_dport *
redirect_devm_cxl_add_dport_by_dev(struct cxl_port *port,
struct device *dport_dev);
static int redirect_devm_cxl_switch_port_decoders_setup(struct cxl_port *port);
+static void redirect_cxl_dport_init_ras_reporting(struct cxl_dport *dport,
+ struct device *host);
+static void redirect_cxl_uport_init_ras_reporting(struct cxl_port *port,
+ struct device *host);
void register_cxl_mock_ops(struct cxl_mock_ops *ops)
{
@@ -25,6 +29,8 @@ void register_cxl_mock_ops(struct cxl_mock_ops *ops)
_devm_cxl_add_dport_by_dev = redirect_devm_cxl_add_dport_by_dev;
_devm_cxl_switch_port_decoders_setup =
redirect_devm_cxl_switch_port_decoders_setup;
+ _cxl_dport_init_ras_reporting = redirect_cxl_dport_init_ras_reporting;
+ _cxl_uport_init_ras_reporting = redirect_cxl_uport_init_ras_reporting;
}
EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
@@ -35,6 +41,9 @@ void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
_devm_cxl_switch_port_decoders_setup =
__devm_cxl_switch_port_decoders_setup;
_devm_cxl_add_dport_by_dev = __devm_cxl_add_dport_by_dev;
+ _cxl_dport_init_ras_reporting = __cxl_dport_init_ras_reporting;
+ _cxl_uport_init_ras_reporting = __cxl_uport_init_ras_reporting;
+
list_del_rcu(&ops->list);
synchronize_srcu(&cxl_mock_srcu);
}
@@ -257,7 +266,8 @@ void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port)
}
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, "CXL");
-void __wrap_cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
+void redirect_cxl_dport_init_ras_reporting(struct cxl_dport *dport,
+ struct device *host)
{
int index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
@@ -267,7 +277,18 @@ void __wrap_cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device
put_cxl_mock_ops(index);
}
-EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dport_init_ras_reporting, "CXL");
+
+void redirect_cxl_uport_init_ras_reporting(struct cxl_port *port,
+ struct device *host)
+{
+ int index;
+ struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
+
+ if (!ops || !ops->is_mock_port(port->uport_dev))
+ cxl_uport_init_ras_reporting(port, host);
+
+ put_cxl_mock_ops(index);
+}
struct cxl_dport *redirect_devm_cxl_add_dport_by_dev(struct cxl_port *port,
struct device *dport_dev)
--
2.37.3
On 11/4/25 10:02 AM, Terry Bowman wrote:
> CXL Endpoint (EP) Ports may include Root Ports (RP) or Downstream Switch
> Ports (DSP). CXL RPs and DSPs contain RAS registers that require memory
> mapping to enable RAS logging. This initialization is currently missing and
> must be added for CXL RPs and DSPs.
>
> Update cxl_dport_init_ras_reporting() to support RP and DSP RAS mapping.
> Add alongside the existing Restricted CXL Host Downstream Port RAS mapping.
>
> Update cxl_endpoint_port_probe() to invoke cxl_dport_init_ras_reporting().
> This will initiate the RAS mapping for CXL RPs and DSPs when each CXL EP is
> created and added to the EP port.
>
> Make a call to cxl_port_setup_regs() in cxl_port_add(). This will probe the
> Upstream Port's CXL capabilities' physical location to be used in mapping
> the RAS registers.
>
> Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>>
> ---
>
> Changes in v12->v13:
> - Change as result of dport delay fix. No longer need switchport and
> endport approach. (Terry)
>
> Changes in v11->v12:
> - Add check for dport_parent->rch before calling cxl_dport_init_ras_reporting().
> RCH dports are initialized from cxl_dport_init_ras_reporting cxl_mem_probe().
>
> Changes in v10->v11:
> - Use local pointer for readability in cxl_switch_port_init_ras() (Jonathan Cameron)
> - Rename port to be ep in cxl_endpoint_port_init_ras() (Dave Jiang)
> - Rename dport to be parent_dport in cxl_endpoint_port_init_ras()
> and cxl_switch_port_init_ras() (Dave Jiang)
> - Port helper changes were in cxl/port.c, now in core/ras.c (Dave Jiang)
> ---
> drivers/cxl/core/port.c | 4 ++++
> drivers/cxl/core/ras.c | 12 ++++++++++++
> drivers/cxl/cxl.h | 2 ++
> drivers/cxl/cxlpci.h | 4 ++++
> drivers/cxl/mem.c | 3 ++-
> 5 files changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index 8128fd2b5b31..48f6a1492544 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -1194,6 +1194,8 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
> return ERR_PTR(rc);
> }
> port->component_reg_phys = CXL_RESOURCE_NONE;
> + if (!is_cxl_endpoint(port) && dev_is_pci(port->uport_dev))
> + cxl_uport_init_ras_reporting(port, &port->dev);
> }
>
> get_device(dport_dev);
> @@ -1623,6 +1625,8 @@ static struct cxl_dport *cxl_port_add_dport(struct cxl_port *port,
>
> cxl_switch_parse_cdat(new_dport);
>
> + cxl_dport_init_ras_reporting(new_dport, &port->dev);
> +
> if (ida_is_empty(&port->decoder_ida)) {
> rc = devm_cxl_switch_port_decoders_setup(port);
> if (rc)
> diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
> index 246dfe56617a..19d9ffe885bf 100644
> --- a/drivers/cxl/core/ras.c
> +++ b/drivers/cxl/core/ras.c
> @@ -162,6 +162,18 @@ void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
> }
> EXPORT_SYMBOL_NS_GPL(cxl_dport_init_ras_reporting, "CXL");
>
> +void cxl_uport_init_ras_reporting(struct cxl_port *port,
> + struct device *host)
> +{
> + struct cxl_register_map *map = &port->reg_map;
> +
> + map->host = host;
> + if (cxl_map_component_regs(map, &port->uport_regs,
> + BIT(CXL_CM_CAP_CAP_ID_RAS)))
> + dev_dbg(&port->dev, "Failed to map RAS capability\n");
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_uport_init_ras_reporting, "CXL");
> +
> void cxl_handle_cor_ras(struct device *dev, u64 serial, void __iomem *ras_base)
> {
> void __iomem *addr;
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index 259ed4b676e1..b7654d40dc9e 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -599,6 +599,7 @@ struct cxl_dax_region {
> * @parent_dport: dport that points to this port in the parent
> * @decoder_ida: allocator for decoder ids
> * @reg_map: component and ras register mapping parameters
> + * @uport_regs: mapped component registers
> * @nr_dports: number of entries in @dports
> * @hdm_end: track last allocated HDM decoder instance for allocation ordering
> * @commit_end: cursor to track highest committed decoder for commit ordering
> @@ -620,6 +621,7 @@ struct cxl_port {
> struct cxl_dport *parent_dport;
> struct ida decoder_ida;
> struct cxl_register_map reg_map;
> + struct cxl_component_regs uport_regs;
> int nr_dports;
> int hdm_end;
> int commit_end;
> diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
> index 0c8b6ee7b6de..a0a491e7b5b9 100644
> --- a/drivers/cxl/cxlpci.h
> +++ b/drivers/cxl/cxlpci.h
> @@ -83,6 +83,8 @@ void cxl_cor_error_detected(struct pci_dev *pdev);
> pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
> pci_channel_state_t state);
> void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host);
> +void cxl_uport_init_ras_reporting(struct cxl_port *port,
> + struct device *host);
> #else
> static inline void cxl_cor_error_detected(struct pci_dev *pdev) { }
>
> @@ -94,6 +96,8 @@ static inline pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
>
> static inline void cxl_dport_init_ras_reporting(struct cxl_dport *dport,
> struct device *host) { }
> +static inline void cxl_uport_init_ras_reporting(struct cxl_port *port,
> + struct device *host) { }
> #endif
>
> #endif /* __CXL_PCI_H__ */
> diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
> index 6e6777b7bafb..d2155f45240d 100644
> --- a/drivers/cxl/mem.c
> +++ b/drivers/cxl/mem.c
> @@ -166,7 +166,8 @@ static int cxl_mem_probe(struct device *dev)
> else
> endpoint_parent = &parent_port->dev;
>
> - cxl_dport_init_ras_reporting(dport, dev);
> + if (dport->rch)
> + cxl_dport_init_ras_reporting(dport, dev);
>
> scoped_guard(device, endpoint_parent) {
> if (!endpoint_parent->driver) {
On Tue, 4 Nov 2025 11:02:54 -0600 Terry Bowman <terry.bowman@amd.com> wrote: > CXL Endpoint (EP) Ports may include Root Ports (RP) or Downstream Switch > Ports (DSP). CXL RPs and DSPs contain RAS registers that require memory > mapping to enable RAS logging. This initialization is currently missing and > must be added for CXL RPs and DSPs. > > Update cxl_dport_init_ras_reporting() to support RP and DSP RAS mapping. > Add alongside the existing Restricted CXL Host Downstream Port RAS mapping. > > Update cxl_endpoint_port_probe() to invoke cxl_dport_init_ras_reporting(). > This will initiate the RAS mapping for CXL RPs and DSPs when each CXL EP is > created and added to the EP port. > > Make a call to cxl_port_setup_regs() in cxl_port_add(). This will probe the > Upstream Port's CXL capabilities' physical location to be used in mapping > the RAS registers. > > Signed-off-by: Terry Bowman <terry.bowman@amd.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
© 2016 - 2025 Red Hat, Inc.