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

Reply via email to