Re: [PATCH RFC v4 5/6] firmware/efi: Process CXL Component Events

From: Smita Koralahalli
Date: Tue Nov 28 2023 - 15:32:51 EST


Hi Ira,

I tested this out. Just one correction below to make it work.

On 11/9/2023 2:07 PM, Ira Weiny wrote:
BIOS can configure memory devices as firmware first. This will send CXL
events to the firmware instead of the OS. The firmware can then send
these events to the OS via UEFI.

UEFI v2.10 section N.2.14 defines a Common Platform Error Record (CPER)
format for CXL Component Events. The format is mostly the same as the
CXL Common Event Record Format. The difference is a GUID is used in
the Section Type to identify the event type.

Add EFI support to detect CXL CPER records and call a notifier chain
with the record data blobs to be processed by the CXL code.

Signed-off-by: Ira Weiny <ira.weiny@xxxxxxxxx>

---
Changes from RFC v3
[Smita: ensure cper_cxl_event_rec is packed]

Changes from RFC v2
[djbw: use common event structures]
[djbw: remove print in core cper code]
[djbw: export register call as NS_GPL]
[iweiny: fix 0day issues]

Changes from RFC v1
[iweiny: use an enum for know record types and skip converting GUID to UUID]
[iweiny: commit to the UUID not being part of the event record data]
[iweiny: use defines for GUID definitions]
---

[snip]

diff --git a/include/linux/cxl-event.h b/include/linux/cxl-event.h
index 6b689e1efc78..733ab2ab8639 100644
--- a/include/linux/cxl-event.h
+++ b/include/linux/cxl-event.h
@@ -108,4 +108,53 @@ struct cxl_event_record_raw {
union cxl_event event;
} __packed;
+enum cxl_event_type {
+ CXL_CPER_EVENT_GEN_MEDIA,
+ CXL_CPER_EVENT_DRAM,
+ CXL_CPER_EVENT_MEM_MODULE,
+};
+
+#define CPER_CXL_DEVICE_ID_VALID BIT(0)
+#define CPER_CXL_DEVICE_SN_VALID BIT(1)
+#define CPER_CXL_COMP_EVENT_LOG_VALID BIT(2)
+struct cper_cxl_event_rec {
+ struct {
+ u32 length;
+ u64 validation_bits;
+ struct cper_cxl_event_devid {
+ u16 vendor_id;
+ u16 device_id;
+ u8 func_num;
+ u8 device_num;
+ u8 bus_num;
+ u16 segment_num;
+ u16 slot_num; /* bits 2:0 reserved */
+ u8 reserved;
+ } device_id;
+ struct cper_cxl_event_sn {
+ u32 lower_dw;
+ u32 upper_dw;
+ } dev_serial_num;
+ } hdr;
+
+ union cxl_event event;
+} __packed;

__packed attribute just for cper_cxl_event_rec still fails to properly align structure elements. Looks like, __packed attribute is needed for all structs (cper_cxl_event_devid and cper_cxl_event_sn) inside cper_cxl_event_rec.

Seems easier to use global pragma instead.. I could test and obtain the output as expected using pragma..

Thanks,
Smita

+
+struct cxl_cper_notifier_data {
+ enum cxl_event_type event_type;
+ struct cper_cxl_event_rec *rec;
+};
+
+#ifdef CONFIG_UEFI_CPER
+int register_cxl_cper_notifier(struct notifier_block *nb);
+void unregister_cxl_cper_notifier(struct notifier_block *nb);
+#else
+static inline int register_cxl_cper_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline void unregister_cxl_cper_notifier(struct notifier_block *nb) { }
+#endif
+
#endif /* _LINUX_CXL_EVENT_H */