}
 EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL);
 
-static void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
-                                  enum cxl_event_log_type type,
-                                  struct cxl_event_record_raw *record)
+void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
+                           enum cxl_event_log_type type,
+                           enum cxl_event_type event_type,
+                           const uuid_t *uuid, union cxl_event *evt)
 {
-       union cxl_event *evt = &record->event;
-       uuid_t *id = &record->id;
-
-       if (uuid_equal(id, &CXL_EVENT_GEN_MEDIA_UUID))
+       if (event_type == CXL_CPER_EVENT_GEN_MEDIA)
                trace_cxl_general_media(cxlmd, type, &evt->gen_media);
-       else if (uuid_equal(id, &CXL_EVENT_DRAM_UUID))
+       else if (event_type == CXL_CPER_EVENT_DRAM)
                trace_cxl_dram(cxlmd, type, &evt->dram);
-       else if (uuid_equal(id, &CXL_EVENT_MEM_MODULE_UUID))
+       else if (event_type == CXL_CPER_EVENT_MEM_MODULE)
                trace_cxl_memory_module(cxlmd, type, &evt->mem_module);
        else
-               trace_cxl_generic_event(cxlmd, type, id, &evt->generic);
+               trace_cxl_generic_event(cxlmd, type, uuid, &evt->generic);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_event_trace_record, CXL);
+
+static void __cxl_event_trace_record(const struct cxl_memdev *cxlmd,
+                                    enum cxl_event_log_type type,
+                                    struct cxl_event_record_raw *record)
+{
+       enum cxl_event_type ev_type = CXL_CPER_EVENT_GENERIC;
+       const uuid_t *uuid = &record->id;
+
+       if (uuid_equal(uuid, &CXL_EVENT_GEN_MEDIA_UUID))
+               ev_type = CXL_CPER_EVENT_GEN_MEDIA;
+       else if (uuid_equal(uuid, &CXL_EVENT_DRAM_UUID))
+               ev_type = CXL_CPER_EVENT_DRAM;
+       else if (uuid_equal(uuid, &CXL_EVENT_MEM_MODULE_UUID))
+               ev_type = CXL_CPER_EVENT_MEM_MODULE;
+
+       cxl_event_trace_record(cxlmd, type, ev_type, uuid, &record->event);
 }
 
 static int cxl_clear_event_record(struct cxl_memdev_state *mds,
                        break;
 
                for (i = 0; i < nr_rec; i++)
-                       cxl_event_trace_record(cxlmd, type,
-                                              &payload->records[i]);
+                       __cxl_event_trace_record(cxlmd, type,
+                                                &payload->records[i]);
 
                if (payload->flags & CXL_GET_EVENT_FLAG_OVERFLOW)
                        trace_cxl_overflow(cxlmd, type, payload);
 
 void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds,
                                  unsigned long *cmds);
 void cxl_mem_get_event_records(struct cxl_memdev_state *mds, u32 status);
+void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
+                           enum cxl_event_log_type type,
+                           enum cxl_event_type event_type,
+                           const uuid_t *uuid, union cxl_event *evt);
 int cxl_set_timestamp(struct cxl_memdev_state *mds);
 int cxl_poison_state_init(struct cxl_memdev_state *mds);
 int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
 
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
+#include <asm-generic/unaligned.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/moduleparam.h>
 #include <linux/module.h>
        },
 };
 
+#define CXL_EVENT_HDR_FLAGS_REC_SEVERITY GENMASK(1, 0)
+static void cxl_cper_event_call(enum cxl_event_type ev_type,
+                               struct cxl_cper_event_rec *rec)
+{
+       struct cper_cxl_event_devid *device_id = &rec->hdr.device_id;
+       struct pci_dev *pdev __free(pci_dev_put) = NULL;
+       enum cxl_event_log_type log_type;
+       struct cxl_dev_state *cxlds;
+       unsigned int devfn;
+       u32 hdr_flags;
+
+       devfn = PCI_DEVFN(device_id->device_num, device_id->func_num);
+       pdev = pci_get_domain_bus_and_slot(device_id->segment_num,
+                                          device_id->bus_num, devfn);
+       if (!pdev)
+               return;
+
+       guard(pci_dev)(pdev);
+       if (pdev->driver != &cxl_pci_driver)
+               return;
+
+       cxlds = pci_get_drvdata(pdev);
+       if (!cxlds)
+               return;
+
+       /* Fabricate a log type */
+       hdr_flags = get_unaligned_le24(rec->event.generic.hdr.flags);
+       log_type = FIELD_GET(CXL_EVENT_HDR_FLAGS_REC_SEVERITY, hdr_flags);
+
+       cxl_event_trace_record(cxlds->cxlmd, log_type, ev_type,
+                              &uuid_null, &rec->event);
+}
+
+static int __init cxl_pci_driver_init(void)
+{
+       int rc;
+
+       rc = cxl_cper_register_callback(cxl_cper_event_call);
+       if (rc)
+               return rc;
+
+       rc = pci_register_driver(&cxl_pci_driver);
+       if (rc)
+               cxl_cper_unregister_callback(cxl_cper_event_call);
+
+       return rc;
+}
+
+static void __exit cxl_pci_driver_exit(void)
+{
+       pci_unregister_driver(&cxl_pci_driver);
+       cxl_cper_unregister_callback(cxl_cper_event_call);
+}
+
+module_init(cxl_pci_driver_init);
+module_exit(cxl_pci_driver_exit);
 MODULE_LICENSE("GPL v2");
-module_pci_driver(cxl_pci_driver);
 MODULE_IMPORT_NS(CXL);