Skip to content

Commit 3601311

Browse files
committed
Merge branch 'for-6.8/cxl-cper' into for-6.8/cxl
Pick up the CPER to CXL driver integration work for v6.8. Some additional cleanup of cper_estatus_print() messages is needed, but that is to be handled incrementally.
2 parents e16bf7e + dc97f63 commit 3601311

9 files changed

Lines changed: 470 additions & 208 deletions

File tree

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5245,6 +5245,7 @@ M: Dan Williams <dan.j.williams@intel.com>
52455245
L: linux-cxl@vger.kernel.org
52465246
S: Maintained
52475247
F: drivers/cxl/
5248+
F: include/linux/cxl-event.h
52485249
F: include/uapi/linux/cxl_mem.h
52495250
F: tools/testing/cxl/
52505251

drivers/acpi/apei/ghes.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <linux/interrupt.h>
2727
#include <linux/timer.h>
2828
#include <linux/cper.h>
29+
#include <linux/cxl-event.h>
2930
#include <linux/platform_device.h>
3031
#include <linux/mutex.h>
3132
#include <linux/ratelimit.h>
@@ -657,6 +658,78 @@ static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
657658
schedule_work(&entry->work);
658659
}
659660

661+
/*
662+
* Only a single callback can be registered for CXL CPER events.
663+
*/
664+
static DECLARE_RWSEM(cxl_cper_rw_sem);
665+
static cxl_cper_callback cper_callback;
666+
667+
/* CXL Event record UUIDs are formatted as GUIDs and reported in section type */
668+
669+
/*
670+
* General Media Event Record
671+
* CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43
672+
*/
673+
#define CPER_SEC_CXL_GEN_MEDIA_GUID \
674+
GUID_INIT(0xfbcd0a77, 0xc260, 0x417f, \
675+
0x85, 0xa9, 0x08, 0x8b, 0x16, 0x21, 0xeb, 0xa6)
676+
677+
/*
678+
* DRAM Event Record
679+
* CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44
680+
*/
681+
#define CPER_SEC_CXL_DRAM_GUID \
682+
GUID_INIT(0x601dcbb3, 0x9c06, 0x4eab, \
683+
0xb8, 0xaf, 0x4e, 0x9b, 0xfb, 0x5c, 0x96, 0x24)
684+
685+
/*
686+
* Memory Module Event Record
687+
* CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45
688+
*/
689+
#define CPER_SEC_CXL_MEM_MODULE_GUID \
690+
GUID_INIT(0xfe927475, 0xdd59, 0x4339, \
691+
0xa5, 0x86, 0x79, 0xba, 0xb1, 0x13, 0xb7, 0x74)
692+
693+
static void cxl_cper_post_event(enum cxl_event_type event_type,
694+
struct cxl_cper_event_rec *rec)
695+
{
696+
if (rec->hdr.length <= sizeof(rec->hdr) ||
697+
rec->hdr.length > sizeof(*rec)) {
698+
pr_err(FW_WARN "CXL CPER Invalid section length (%u)\n",
699+
rec->hdr.length);
700+
return;
701+
}
702+
703+
if (!(rec->hdr.validation_bits & CPER_CXL_COMP_EVENT_LOG_VALID)) {
704+
pr_err(FW_WARN "CXL CPER invalid event\n");
705+
return;
706+
}
707+
708+
guard(rwsem_read)(&cxl_cper_rw_sem);
709+
if (cper_callback)
710+
cper_callback(event_type, rec);
711+
}
712+
713+
int cxl_cper_register_callback(cxl_cper_callback callback)
714+
{
715+
guard(rwsem_write)(&cxl_cper_rw_sem);
716+
if (cper_callback)
717+
return -EINVAL;
718+
cper_callback = callback;
719+
return 0;
720+
}
721+
EXPORT_SYMBOL_NS_GPL(cxl_cper_register_callback, CXL);
722+
723+
int cxl_cper_unregister_callback(cxl_cper_callback callback)
724+
{
725+
guard(rwsem_write)(&cxl_cper_rw_sem);
726+
if (callback != cper_callback)
727+
return -EINVAL;
728+
cper_callback = NULL;
729+
return 0;
730+
}
731+
EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_callback, CXL);
732+
660733
static bool ghes_do_proc(struct ghes *ghes,
661734
const struct acpi_hest_generic_status *estatus)
662735
{
@@ -690,6 +763,22 @@ static bool ghes_do_proc(struct ghes *ghes,
690763
}
691764
else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
692765
queued = ghes_handle_arm_hw_error(gdata, sev);
766+
} else if (guid_equal(sec_type, &CPER_SEC_CXL_GEN_MEDIA_GUID)) {
767+
struct cxl_cper_event_rec *rec =
768+
acpi_hest_get_payload(gdata);
769+
770+
cxl_cper_post_event(CXL_CPER_EVENT_GEN_MEDIA, rec);
771+
} else if (guid_equal(sec_type, &CPER_SEC_CXL_DRAM_GUID)) {
772+
struct cxl_cper_event_rec *rec =
773+
acpi_hest_get_payload(gdata);
774+
775+
cxl_cper_post_event(CXL_CPER_EVENT_DRAM, rec);
776+
} else if (guid_equal(sec_type,
777+
&CPER_SEC_CXL_MEM_MODULE_GUID)) {
778+
struct cxl_cper_event_rec *rec =
779+
acpi_hest_get_payload(gdata);
780+
781+
cxl_cper_post_event(CXL_CPER_EVENT_MEM_MODULE, rec);
693782
} else {
694783
void *err = acpi_hest_get_payload(gdata);
695784

drivers/cxl/core/mbox.c

Lines changed: 33 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -837,54 +837,37 @@ int cxl_enumerate_cmds(struct cxl_memdev_state *mds)
837837
}
838838
EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL);
839839

840-
/*
841-
* General Media Event Record
842-
* CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43
843-
*/
844-
static const uuid_t gen_media_event_uuid =
845-
UUID_INIT(0xfbcd0a77, 0xc260, 0x417f,
846-
0x85, 0xa9, 0x08, 0x8b, 0x16, 0x21, 0xeb, 0xa6);
847-
848-
/*
849-
* DRAM Event Record
850-
* CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44
851-
*/
852-
static const uuid_t dram_event_uuid =
853-
UUID_INIT(0x601dcbb3, 0x9c06, 0x4eab,
854-
0xb8, 0xaf, 0x4e, 0x9b, 0xfb, 0x5c, 0x96, 0x24);
855-
856-
/*
857-
* Memory Module Event Record
858-
* CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45
859-
*/
860-
static const uuid_t mem_mod_event_uuid =
861-
UUID_INIT(0xfe927475, 0xdd59, 0x4339,
862-
0xa5, 0x86, 0x79, 0xba, 0xb1, 0x13, 0xb7, 0x74);
863-
864-
static void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
865-
enum cxl_event_log_type type,
866-
struct cxl_event_record_raw *record)
840+
void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
841+
enum cxl_event_log_type type,
842+
enum cxl_event_type event_type,
843+
const uuid_t *uuid, union cxl_event *evt)
867844
{
868-
uuid_t *id = &record->hdr.id;
869-
870-
if (uuid_equal(id, &gen_media_event_uuid)) {
871-
struct cxl_event_gen_media *rec =
872-
(struct cxl_event_gen_media *)record;
845+
if (event_type == CXL_CPER_EVENT_GEN_MEDIA)
846+
trace_cxl_general_media(cxlmd, type, &evt->gen_media);
847+
else if (event_type == CXL_CPER_EVENT_DRAM)
848+
trace_cxl_dram(cxlmd, type, &evt->dram);
849+
else if (event_type == CXL_CPER_EVENT_MEM_MODULE)
850+
trace_cxl_memory_module(cxlmd, type, &evt->mem_module);
851+
else
852+
trace_cxl_generic_event(cxlmd, type, uuid, &evt->generic);
853+
}
854+
EXPORT_SYMBOL_NS_GPL(cxl_event_trace_record, CXL);
873855

874-
trace_cxl_general_media(cxlmd, type, rec);
875-
} else if (uuid_equal(id, &dram_event_uuid)) {
876-
struct cxl_event_dram *rec = (struct cxl_event_dram *)record;
856+
static void __cxl_event_trace_record(const struct cxl_memdev *cxlmd,
857+
enum cxl_event_log_type type,
858+
struct cxl_event_record_raw *record)
859+
{
860+
enum cxl_event_type ev_type = CXL_CPER_EVENT_GENERIC;
861+
const uuid_t *uuid = &record->id;
877862

878-
trace_cxl_dram(cxlmd, type, rec);
879-
} else if (uuid_equal(id, &mem_mod_event_uuid)) {
880-
struct cxl_event_mem_module *rec =
881-
(struct cxl_event_mem_module *)record;
863+
if (uuid_equal(uuid, &CXL_EVENT_GEN_MEDIA_UUID))
864+
ev_type = CXL_CPER_EVENT_GEN_MEDIA;
865+
else if (uuid_equal(uuid, &CXL_EVENT_DRAM_UUID))
866+
ev_type = CXL_CPER_EVENT_DRAM;
867+
else if (uuid_equal(uuid, &CXL_EVENT_MEM_MODULE_UUID))
868+
ev_type = CXL_CPER_EVENT_MEM_MODULE;
882869

883-
trace_cxl_memory_module(cxlmd, type, rec);
884-
} else {
885-
/* For unknown record types print just the header */
886-
trace_cxl_generic_event(cxlmd, type, record);
887-
}
870+
cxl_event_trace_record(cxlmd, type, ev_type, uuid, &record->event);
888871
}
889872

890873
static int cxl_clear_event_record(struct cxl_memdev_state *mds,
@@ -927,7 +910,10 @@ static int cxl_clear_event_record(struct cxl_memdev_state *mds,
927910
*/
928911
i = 0;
929912
for (cnt = 0; cnt < total; cnt++) {
930-
payload->handles[i++] = get_pl->records[cnt].hdr.handle;
913+
struct cxl_event_record_raw *raw = &get_pl->records[cnt];
914+
struct cxl_event_generic *gen = &raw->event.generic;
915+
916+
payload->handles[i++] = gen->hdr.handle;
931917
dev_dbg(mds->cxlds.dev, "Event log '%d': Clearing %u\n", log,
932918
le16_to_cpu(payload->handles[i]));
933919

@@ -992,8 +978,8 @@ static void cxl_mem_get_records_log(struct cxl_memdev_state *mds,
992978
break;
993979

994980
for (i = 0; i < nr_rec; i++)
995-
cxl_event_trace_record(cxlmd, type,
996-
&payload->records[i]);
981+
__cxl_event_trace_record(cxlmd, type,
982+
&payload->records[i]);
997983

998984
if (payload->flags & CXL_GET_EVENT_FLAG_OVERFLOW)
999985
trace_cxl_overflow(cxlmd, type, payload);

drivers/cxl/core/trace.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ TRACE_EVENT(cxl_overflow,
181181
* 1) Add CXL_EVT_TP_entry to TP_STRUCT__entry
182182
* 2) Use CXL_EVT_TP_fast_assign within TP_fast_assign;
183183
* pass the dev, log, and CXL event header
184+
* NOTE: The uuid must be assigned by the specific trace event
184185
* 3) Use CXL_EVT_TP_printk() instead of TP_printk()
185186
*
186187
* See the generic_event tracepoint as an example.
@@ -203,7 +204,6 @@ TRACE_EVENT(cxl_overflow,
203204
__assign_str(host, dev_name((cxlmd)->dev.parent)); \
204205
__entry->log = (l); \
205206
__entry->serial = (cxlmd)->cxlds->serial; \
206-
memcpy(&__entry->hdr_uuid, &(hdr).id, sizeof(uuid_t)); \
207207
__entry->hdr_length = (hdr).length; \
208208
__entry->hdr_flags = get_unaligned_le24((hdr).flags); \
209209
__entry->hdr_handle = le16_to_cpu((hdr).handle); \
@@ -225,18 +225,19 @@ TRACE_EVENT(cxl_overflow,
225225
TRACE_EVENT(cxl_generic_event,
226226

227227
TP_PROTO(const struct cxl_memdev *cxlmd, enum cxl_event_log_type log,
228-
struct cxl_event_record_raw *rec),
228+
const uuid_t *uuid, struct cxl_event_generic *gen_rec),
229229

230-
TP_ARGS(cxlmd, log, rec),
230+
TP_ARGS(cxlmd, log, uuid, gen_rec),
231231

232232
TP_STRUCT__entry(
233233
CXL_EVT_TP_entry
234234
__array(u8, data, CXL_EVENT_RECORD_DATA_LENGTH)
235235
),
236236

237237
TP_fast_assign(
238-
CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr);
239-
memcpy(__entry->data, &rec->data, CXL_EVENT_RECORD_DATA_LENGTH);
238+
CXL_EVT_TP_fast_assign(cxlmd, log, gen_rec->hdr);
239+
memcpy(&__entry->hdr_uuid, uuid, sizeof(uuid_t));
240+
memcpy(__entry->data, gen_rec->data, CXL_EVENT_RECORD_DATA_LENGTH);
240241
),
241242

242243
CXL_EVT_TP_printk("%s",
@@ -337,6 +338,7 @@ TRACE_EVENT(cxl_general_media,
337338

338339
TP_fast_assign(
339340
CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr);
341+
memcpy(&__entry->hdr_uuid, &CXL_EVENT_GEN_MEDIA_UUID, sizeof(uuid_t));
340342

341343
/* General Media */
342344
__entry->dpa = le64_to_cpu(rec->phys_addr);
@@ -423,6 +425,7 @@ TRACE_EVENT(cxl_dram,
423425

424426
TP_fast_assign(
425427
CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr);
428+
memcpy(&__entry->hdr_uuid, &CXL_EVENT_DRAM_UUID, sizeof(uuid_t));
426429

427430
/* DRAM */
428431
__entry->dpa = le64_to_cpu(rec->phys_addr);
@@ -570,6 +573,7 @@ TRACE_EVENT(cxl_memory_module,
570573

571574
TP_fast_assign(
572575
CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr);
576+
memcpy(&__entry->hdr_uuid, &CXL_EVENT_MEM_MODULE_UUID, sizeof(uuid_t));
573577

574578
/* Memory Module Event */
575579
__entry->event_type = rec->event_type;

0 commit comments

Comments
 (0)