diff --git a/drivers/gpu/drm/amd/ras/core/core.c b/drivers/gpu/drm/amd/ras/core/core.c index 9cfc33f3ab96..34353ac12b92 100644 --- a/drivers/gpu/drm/amd/ras/core/core.c +++ b/drivers/gpu/drm/amd/ras/core/core.c @@ -864,3 +864,14 @@ int ras_core_get_module_param(struct ras_core_context *ras_core, return 0; } + +int ras_core_add_log_event(struct ras_core_context *ras_core, + uint32_t event, void *data, uint32_t data_sz) +{ + if (event >= RAS_LOG_EVENT_COUNT_MAX) { + RAS_DEV_ERR(ras_core->dev, "Invalid ras log event(0x%x)!\n", event); + return -EINVAL; + } + + return ras_log_ring_add_log_event(ras_core, event, data, data_sz, NULL); +} diff --git a/drivers/gpu/drm/amd/ras/core/log_ring.c b/drivers/gpu/drm/amd/ras/core/log_ring.c index 28cda7528e2b..fb42449fbd6c 100644 --- a/drivers/gpu/drm/amd/ras/core/log_ring.c +++ b/drivers/gpu/drm/amd/ras/core/log_ring.c @@ -222,7 +222,7 @@ void ras_log_ring_destroy_batch_tag(struct ras_core_context *ras_core, kfree(batch_tag); } -void ras_log_ring_add_log_event(struct ras_core_context *ras_core, +int ras_log_ring_add_log_event(struct ras_core_context *ras_core, enum ras_log_event event, void *data, uint32_t size, struct ras_log_batch_tag *batch_tag) { @@ -232,6 +232,12 @@ void ras_log_ring_add_log_event(struct ras_core_context *ras_core, uint64_t socket_id; void *obj; + if (size > sizeof(union ras_log_body)) { + RAS_DEV_ERR(ras_core->dev, + "Log event(0x%x) data size exceeded buffer!\n", event); + return -EINVAL; + } + obj = mempool_alloc_preallocated(log_ring->ras_log_mempool); if (!obj || (ras_log_ring_get_logged_ecc_count(ras_core) >= RAS_LOG_MEMPOOL_SIZE)) { @@ -242,7 +248,7 @@ void ras_log_ring_add_log_event(struct ras_core_context *ras_core, if (!obj) { RAS_DEV_ERR(ras_core->dev, "ERROR: Failed to alloc ras log buffer!\n"); - return; + return -ENOMEM; } log = (struct ras_log_info *)obj; @@ -252,8 +258,10 @@ void ras_log_ring_add_log_event(struct ras_core_context *ras_core, batch_tag ? batch_tag->timestamp : ktime_get_real_ns(); log->event = event; - if (data && size && size <= sizeof(log->body)) + if (data && size && size <= sizeof(log->body)) { memcpy(&log->body, data, size); + log->size = size; + } if (event == RAS_LOG_EVENT_RMA) { memcpy(&log->body.aca_reg, ras_rma_aca_reg, sizeof(log->body.aca_reg)); @@ -261,9 +269,10 @@ void ras_log_ring_add_log_event(struct ras_core_context *ras_core, socket_id = dev_info.socket_id; log->body.aca_reg.regs[ACA_REG_IDX__IPID] |= ((socket_id / 4) & 0x01); log->body.aca_reg.regs[ACA_REG_IDX__IPID] |= (((socket_id % 4) & 0x3) << 44); + log->size = sizeof(log->body.aca_reg); } - ras_log_ring_add_data(ras_core, log, batch_tag); + return ras_log_ring_add_data(ras_core, log, batch_tag); } static int ras_log_ring_lookup_data(struct ras_core_context *ras_core, diff --git a/drivers/gpu/drm/amd/ras/core/log_ring.h b/drivers/gpu/drm/amd/ras/core/log_ring.h index bcefd228aad3..ed68664bf3c6 100644 --- a/drivers/gpu/drm/amd/ras/core/log_ring.h +++ b/drivers/gpu/drm/amd/ras/core/log_ring.h @@ -65,6 +65,7 @@ struct ras_log_info { uint64_t seqno; uint64_t timestamp; enum ras_log_event event; + uint32_t size; union ras_log_body body; }; @@ -97,7 +98,7 @@ int ras_log_ring_sw_fini(struct ras_core_context *ras_core); struct ras_log_batch_tag *ras_log_ring_create_batch_tag(struct ras_core_context *ras_core); void ras_log_ring_destroy_batch_tag(struct ras_core_context *ras_core, struct ras_log_batch_tag *tag); -void ras_log_ring_add_log_event(struct ras_core_context *ras_core, +int ras_log_ring_add_log_event(struct ras_core_context *ras_core, enum ras_log_event event, void *data, uint32_t size, struct ras_log_batch_tag *batch_tag); diff --git a/drivers/gpu/drm/amd/ras/core/ras.h b/drivers/gpu/drm/amd/ras/core/ras.h index 3bfee0eeb5c5..f1f310a7a299 100644 --- a/drivers/gpu/drm/amd/ras/core/ras.h +++ b/drivers/gpu/drm/amd/ras/core/ras.h @@ -494,4 +494,6 @@ bool ras_core_early_init_service_enabled(struct ras_core_context *ras_core); int ras_core_eeprom_early_init_service(struct ras_core_context *ras_core); int ras_core_get_module_param(struct ras_core_context *ras_core, struct ras_module_param *param); +int ras_core_add_log_event(struct ras_core_context *ras_core, + uint32_t event, void *data, uint32_t data_sz); #endif