[PATCH 006/109] drm/amd/ras: Introduce BOOT CPER encoding function
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: Xiang Liu <[email protected]> Introduce new fields for BOOT CPER encoding, only important fields are introduced here due to the cache size limit. Signed-off-by: Xiang Liu <[email protected]> Reviewed-by: Hawking Zhang <[email protected]> Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/ras/core/log_ring.c | 8 +++- drivers/gpu/drm/amd/ras/core/log_ring.h | 11 ++++++ drivers/gpu/drm/amd/ras/core/ras_cper.c | 51 +++++++++++++++++++++++++ drivers/gpu/drm/amd/ras/core/ras_cper.h | 10 ++++- 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/ras/core/log_ring.c b/drivers/gpu/drm/amd/ras/core/log_ring.c index 175c8b3571447..73f075b0f1fdd 100644 --- a/drivers/gpu/drm/amd/ras/core/log_ring.c +++ b/drivers/gpu/drm/amd/ras/core/log_ring.c @@ -251,8 +251,12 @@ void ras_log_ring_add_log_event(struct ras_core_context *ras_core, batch_tag ? batch_tag->timestamp : ras_core_get_utc_second_timestamp(ras_core); log->event = event; - if (data) - memcpy(&log->aca_reg, data, sizeof(log->aca_reg)); + if (data) { + if (event == RAS_LOG_EVENT_BOOT) + memcpy(&log->boot_err_ctx, data, sizeof(log->boot_err_ctx)); + else + memcpy(&log->aca_reg, data, sizeof(log->aca_reg)); + } if (event == RAS_LOG_EVENT_RMA) { memcpy(&log->aca_reg, ras_rma_aca_reg, sizeof(log->aca_reg)); diff --git a/drivers/gpu/drm/amd/ras/core/log_ring.h b/drivers/gpu/drm/amd/ras/core/log_ring.h index 13973add0e5cb..428ad48d08fee 100644 --- a/drivers/gpu/drm/amd/ras/core/log_ring.h +++ b/drivers/gpu/drm/amd/ras/core/log_ring.h @@ -24,6 +24,7 @@ #ifndef __LOG_RING_H__ #define __LOG_RING_H__ #include "aca.h" +#include "ras_cper.h" #define MAX_RECORD_PER_BATCH 32 @@ -38,6 +39,7 @@ enum ras_log_event { RAS_LOG_EVENT_POISON_CONSUMPTION, RAS_LOG_EVENT_RMA, RAS_LOG_EVENT_MCE, + RAS_LOG_EVENT_BOOT, RAS_LOG_EVENT_COUNT_MAX, }; @@ -45,12 +47,21 @@ struct ras_aca_reg { uint64_t regs[ACA_REG_MAX_COUNT]; }; +struct ras_boot_err_ctx { + u8 section_type[16]; + u32 error_severity; + u16 reg_ctx_type; + u16 reg_arr_size; + u64 regs[CPER_OAM_MAX_COUNT]; +}; + struct ras_log_info { uint64_t seqno; uint64_t timestamp; enum ras_log_event event; union { struct ras_aca_reg aca_reg; + struct ras_boot_err_ctx boot_err_ctx; }; }; diff --git a/drivers/gpu/drm/amd/ras/core/ras_cper.c b/drivers/gpu/drm/amd/ras/core/ras_cper.c index fb37c7cc29142..6d7c1cf6a8f4e 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_cper.c +++ b/drivers/gpu/drm/amd/ras/core/ras_cper.c @@ -174,6 +174,19 @@ static int fill_section_runtime(struct ras_core_context *ras_core, return 0; } +static int fill_section_boot(struct ras_core_context *ras_core, struct cper_section_boot *boot, + struct ras_log_info *log) +{ + struct ras_boot_err_ctx *ctx = &log->boot_err_ctx; + struct crashdump_boot *data = &boot->data; + + data->reg_ctx_type = ctx->reg_ctx_type; + data->reg_arr_size = ctx->reg_arr_size; + memcpy(data->msg, ctx->regs, min(boot->data.reg_arr_size, sizeof(data->msg))); + + return 0; +} + static int cper_generate_runtime_record(struct ras_core_context *ras_core, struct cper_section_hdr *hdr, struct ras_log_info *trace_arr, uint32_t arr_num, enum ras_cper_severity sev) @@ -225,6 +238,41 @@ static int cper_generate_fatal_record(struct ras_core_context *ras_core, return 0; } +static int cper_generate_boot_record(struct ras_core_context *ras_core, u8 *buffer, + struct ras_log_info *trace_arr, u32 arr_num) +{ + struct ras_cper_boot_record *record; + int i; + + record = kzalloc(sizeof(*record), GFP_KERNEL); + if (!record) + return -ENOMEM; + + for (i = 0; i < arr_num; i++) { + u32 severity = trace_arr[i].boot_err_ctx.error_severity; + struct ras_cper_guid section_type; + + memcpy(§ion_type, &trace_arr[i].boot_err_ctx.section_type, + min(sizeof(section_type), sizeof(trace_arr[i].boot_err_ctx.section_type))); + + fill_section_hdr(ras_core, &record->hdr, RAS_CPER_TYPE_BOOT, severity, + &trace_arr[i]); + record->hdr.record_length = RAS_HDR_LEN + RAS_SEC_DESC_LEN + RAS_BOOT_SEC_LEN; + record->hdr.sec_cnt = 1; + + fill_section_descriptor(ras_core, &record->descriptor, severity, section_type, + offsetof(struct ras_cper_boot_record, boot), + sizeof(struct ras_cper_boot_record)); + + fill_section_boot(ras_core, &record->boot, &trace_arr[i]); + + memcpy(buffer + (i * record->hdr.record_length), record, record->hdr.record_length); + } + + kfree(record); + return 0; +} + static int cper_get_record_size(enum ras_cper_type type, uint16_t section_count) { int size = 0; @@ -331,6 +379,9 @@ int ras_cper_generate_cper(struct ras_core_context *ras_core, case RAS_LOG_EVENT_UE: cper_generate_fatal_record(ras_core, buffer + saved_size, trace_list, count); break; + case RAS_LOG_EVENT_BOOT: + cper_generate_boot_record(ras_core, buffer + saved_size, trace_list, count); + break; default: RAS_DEV_WARN(ras_core->dev, "Unprocessed trace event: %d\n", trace_list[0].event); break; diff --git a/drivers/gpu/drm/amd/ras/core/ras_cper.h b/drivers/gpu/drm/amd/ras/core/ras_cper.h index 8bfbeb7d78e01..037e8072eb2bc 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_cper.h +++ b/drivers/gpu/drm/amd/ras/core/ras_cper.h @@ -30,11 +30,11 @@ struct ras_cper_guid { }; #define CPER_GUID__INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ - ((struct ras_cper_guid) \ + (struct ras_cper_guid) \ {{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ (b) & 0xff, ((b) >> 8) & 0xff, \ (c) & 0xff, ((c) >> 8) & 0xff, \ - (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} #define CPER_HDR__REV_1 (0x100) #define CPER_SEC__MINOR_REV_1 (0x01) @@ -278,6 +278,12 @@ struct ras_cper_fatal_record { struct cper_section_desc descriptor; struct cper_section_fatal fatal; }; + +struct ras_cper_boot_record { + struct cper_section_hdr hdr; + struct cper_section_desc descriptor; + struct cper_section_boot boot; +}; #pragma pack(pop) #define RAS_HDR_LEN (sizeof(struct cper_section_hdr)) -- 2.55.0