[PATCH 109/109] drm/amd/ras: fix CPER command record retrieval

Alex Deucher <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: Xiang Liu <[email protected]>

The CPER command reports the next batch ID as the latest valid record
and does not handle a request starting at the write pointer. Batch trace
responses also copy only the ACA interpretation of the log union.

Report the latest valid CPER ID, select the preceding record for a write
pointer request, expose a bounded command transfer size, and copy the
complete log body for batch trace records.

Signed-off-by: Xiang Liu <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/ras/core/cmd.c | 23 +++++++++++++++++------
 drivers/gpu/drm/amd/ras/core/cmd.h |  2 ++
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/core/cmd.c b/drivers/gpu/drm/amd/ras/core/cmd.c
index 2eb67ccc562d5..66bd62a819b2e 100644
--- a/drivers/gpu/drm/amd/ras/core/cmd.c
+++ b/drivers/gpu/drm/amd/ras/core/cmd.c
@@ -174,16 +174,18 @@ static int ras_cmd_get_cper_snapshot(struct ras_core_context *ras_core,
 	struct ras_cmd_cper_snapshot_rsp *output_data =
 			(struct ras_cmd_cper_snapshot_rsp *)cmd->output_buff_raw;
 	struct ras_log_batch_overview overview;
+	u64 latest_cper_id;
 
 	if ((cmd->input_size != sizeof(struct ras_cmd_cper_snapshot_req)) ||
 		(cmd->output_buf_size < sizeof(*output_data)))
 		return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
 
 	ras_log_ring_get_batch_overview(ras_core, &overview);
+	latest_cper_id = overview.logged_batch_count ? overview.last_batch_id - 1 : 0;
 
 	output_data->total_cper_num = overview.logged_batch_count;
 	output_data->start_cper_id = overview.first_batch_id;
-	output_data->latest_cper_id = overview.last_batch_id;
+	output_data->latest_cper_id = latest_cper_id;
 
 	output_data->version = 0;
 
@@ -202,7 +204,7 @@ static int ras_cmd_get_cper_records(struct ras_core_context *ras_core,
 	uint32_t nr_batch_logs = MAX_RECORD_PER_BATCH;
 	struct ras_log_batch_overview overview;
 	uint32_t offset = 0, real_data_len = 0;
-	uint64_t batch_id;
+	u64 batch_id, start_batch_id;
 	uint8_t *buf_ptr = (uint8_t *)(uintptr_t)req->buf_ptr;
 	int ret = 0, i, count, valid_batch_count = 0;
 
@@ -221,14 +223,24 @@ static int ras_cmd_get_cper_records(struct ras_core_context *ras_core,
 	}
 
 	ras_log_ring_get_batch_overview(ras_core, &overview);
+
+	start_batch_id = req->cper_start_id;
+	if (overview.logged_batch_count && start_batch_id == overview.last_batch_id)
+		start_batch_id = overview.last_batch_id - 1;
+
 	for (i = 0; i < req->cper_num; i++) {
-		batch_id = req->cper_start_id + i;
+		batch_id = start_batch_id + i;
 		if (batch_id >= overview.last_batch_id)
 			break;
 
 		count = ras_log_ring_get_batch_records(ras_core, batch_id, batch_logs,
 					nr_batch_logs);
 		if (count > 0) {
+			if (offset >= req->buf_size) {
+				ret = -ENOMEM;
+				break;
+			}
+
 			ret = ras_cper_generate_batch_cper(ras_core, batch_logs, count,
 					&buf_ptr[offset], req->buf_size - offset, &real_data_len);
 			if (ret)
@@ -328,9 +340,8 @@ static int ras_cmd_get_batch_trace_records(struct ras_core_context *ras_core,
 				record->seqno = trace_arry[j].seqno;
 				record->timestamp = trace_arry[j].timestamp;
 				record->event = trace_arry[j].event;
-				memcpy(&record->body.aca_reg,
-					&trace_arry[j].body.aca_reg,
-					sizeof(trace_arry[j].body.aca_reg));
+				memcpy(&record->body, &trace_arry[j].body,
+				       sizeof(record->body));
 			}
 		} else {
 			count = 0;
diff --git a/drivers/gpu/drm/amd/ras/core/cmd.h b/drivers/gpu/drm/amd/ras/core/cmd.h
index a37b050e913ab..d3f5ec3c8e5c6 100644
--- a/drivers/gpu/drm/amd/ras/core/cmd.h
+++ b/drivers/gpu/drm/amd/ras/core/cmd.h
@@ -359,6 +359,8 @@ struct ras_cmd_cper_snapshot_rsp {
 	uint64_t latest_cper_id;
 };
 
+#define RAS_CMD_MAX_CPER_BUF_SZ	(2 * 1024U * 1024U) /* 2 MiB */
+
 struct ras_cmd_cper_record_req {
 	struct ras_cmd_dev_handle dev;
 	uint64_t cper_start_id;
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.