diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index c3c82c051d73..7e3770f7a955 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -815,6 +815,89 @@ static void cxl_disable_rch_root_ints(struct cxl_dport *dport)
 	}
 }
 
+static int match_uport(struct device *dev, const void *data)
+{
+	struct device *uport_dev = (struct device *)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_pci_port_ras(struct pci_dev *pdev)
+{
+	void __iomem *ras_base;
+	struct cxl_port *port;
+
+	if (!pdev)
+		return NULL;
+
+	if ((pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT) ||
+	    (pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM)) {
+		struct cxl_dport *dport;
+
+		port = find_cxl_port(&pdev->dev, &dport);
+		ras_base = dport ? dport->regs.ras : NULL;
+		put_device(&port->dev);
+		return ras_base;
+	} else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_UPSTREAM) {
+		struct device *port_dev __free(put_device);
+
+		port_dev = bus_find_device(&cxl_bus_type, NULL, &pdev->dev, match_uport);
+		if (!port_dev)
+			return NULL;
+
+		port = to_cxl_port(port_dev);
+		if (!port)
+			return NULL;
+
+		ras_base = port ? port->uport_regs.ras : NULL;
+		return ras_base;
+	}
+
+	return NULL;
+}
+
+void cxl_cor_port_err_detected(struct pci_dev *pdev)
+{
+	void __iomem *ras_base = cxl_pci_port_ras(pdev);
+
+	__cxl_handle_cor_ras(&pdev->dev, ras_base);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_cor_port_err_detected, CXL);
+
+pci_ers_result_t cxl_port_err_detected(struct pci_dev *pdev, pci_channel_state_t state)
+{
+	void __iomem *ras_base = cxl_pci_port_ras(pdev);
+	bool ue;
+
+	ue = __cxl_handle_ras(&pdev->dev, ras_base);
+	if (ue)
+		return PCI_ERS_RESULT_PANIC;
+
+	switch (state) {
+	case pci_channel_io_normal:
+		dev_err(&pdev->dev, "%s():%d: pci_channel_io_normal\n",
+			__func__, __LINE__);
+		return PCI_ERS_RESULT_CAN_RECOVER;
+	case pci_channel_io_frozen:
+		dev_err(&pdev->dev, "%s():%d: pci_channel_io_frozen\n",
+			__func__, __LINE__);
+		return PCI_ERS_RESULT_NEED_RESET;
+	case pci_channel_io_perm_failure:
+		dev_err(&pdev->dev, "%s():%d: pci_channel_io_perm_failure\n",
+			__func__, __LINE__);
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_port_err_detected, CXL);
+
 void cxl_uport_init_aer(struct cxl_port *port)
 {
 	/* uport may have more than 1 downstream EP. Check if already mapped. */
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 7a5f2c33223e..06fcde4b88b5 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -10,6 +10,7 @@
 #include <linux/bitops.h>
 #include <linux/log2.h>
 #include <linux/node.h>
+#include <linux/pci.h>
 #include <linux/io.h>
 
 extern const struct nvdimm_security_ops *cxl_security_ops;
@@ -901,6 +902,10 @@ void cxl_coordinates_combine(struct access_coordinate *out,
 
 bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
 
+pci_ers_result_t cxl_port_err_detected(struct pci_dev *pdev,
+				       pci_channel_state_t state);
+void cxl_cor_port_err_detected(struct pci_dev *pdev);
+
 /*
  * Unit test builds overrides this to __weak, find the 'strong' version
  * of these symbols in tools/testing/cxl/.
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 4be35dc22202..9179b34c35bb 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -978,6 +978,11 @@ static void cxl_reset_done(struct pci_dev *pdev)
 	}
 }
 
+static struct cxl_port_err_hndlrs cxl_port_hndlrs = {
+	.error_detected = cxl_port_err_detected,
+	.cor_error_detected = cxl_cor_port_err_detected
+};
+
 static const struct pci_error_handlers cxl_error_handlers = {
 	.error_detected	= cxl_error_detected,
 	.slot_reset	= cxl_slot_reset,
@@ -1054,11 +1059,14 @@ static int __init cxl_pci_driver_init(void)
 	if (rc)
 		pci_unregister_driver(&cxl_pci_driver);
 
+	register_cxl_port_hndlrs(&cxl_port_hndlrs);
+
 	return rc;
 }
 
 static void __exit cxl_pci_driver_exit(void)
 {
+	unregister_cxl_port_hndlrs();
 	cxl_cper_unregister_work(&cxl_cper_work);
 	cancel_work_sync(&cxl_cper_work);
 	pci_unregister_driver(&cxl_pci_driver);
