From 4ec227c1586fedebfe0f50761fc507fc443b089e Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Wed, 10 Dec 2025 12:15:56 +0530 Subject: [PATCH] drm/amd/display: Fix 64-bit state pointer passed as 32-bit GPINT response buffer edp_pr_get_state() incorrectly casts a uint64_t * to uint32_t * when calling dc_wake_and_execute_gpint(). The GPINT path writes only 32 bits, leaving the upper 32 bits of the u64 output uninitialized. Replace the cast with a u32 temporary and copy the result into the u64 pointer. Fixes the below: drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_edp_panel_control.c 1448 bool edp_pr_get_state(const struct dc_link *link, uint64_t *state) ^^^^^^^^^^^^^^^ 1449 { ... 1457 do { 1458 // Send gpint command and wait for ack --> 1459 if (!dc_wake_and_execute_gpint(dc->ctx, DMUB_GPINT__GET_REPLAY_STATE, panel_inst, 1460 (uint32_t *)state, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) { ^^^^^^^^^^^^^^^^^ The dc_wake_and_execute_gpint() function doesn't take a u64, it takes a u32. It tries to initialize the state to zero at the start but that's not going to work because of the type mismatch. It suggests that callers are allowed to pass uninitialized data to edp_pr_get_state() but at present there are no callers so this is only a bug in the code but doesn't affect runtime. 1461 // Return invalid state when GPINT times out 1462 *state = PR_STATE_INVALID; 1463 } Fixes: 74ce00932e7e ("drm/amd/display: Refactor panel replay set dmub cmd flow") Reported by: Dan Carpenter Cc: Robin Chen Cc: Jack Chang Cc: Leon Huang Cc: Alex Hung Cc: Aurabindo Pillai Cc: Roman Li Cc: Harry Wentland Cc: Tom Chung Signed-off-by: Srinivasan Shanmugam Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Deucher --- .../amd/display/dc/link/protocols/link_edp_panel_control.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 0b05ee9f6ea1..cf06b9b62e1d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -1450,6 +1450,7 @@ bool edp_pr_get_state(const struct dc_link *link, uint64_t *state) const struct dc *dc = link->ctx->dc; unsigned int panel_inst = 0; uint32_t retry_count = 0; + uint32_t replay_state = 0; if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) return false; @@ -1457,10 +1458,12 @@ bool edp_pr_get_state(const struct dc_link *link, uint64_t *state) do { // Send gpint command and wait for ack if (!dc_wake_and_execute_gpint(dc->ctx, DMUB_GPINT__GET_REPLAY_STATE, panel_inst, - (uint32_t *)state, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) { + &replay_state, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) { // Return invalid state when GPINT times out - *state = PR_STATE_INVALID; + replay_state = PR_STATE_INVALID; } + /* Copy 32-bit result into 64-bit output */ + *state = replay_state; } while (++retry_count <= 1000 && *state == PR_STATE_INVALID); // Assert if max retry hit -- 2.47.3