[AMD Official Use Only - AMD Internal Distribution Only]

Reviewed-by: Aurabindo Pillai <[email protected]>

--

Regards,
Jay
________________________________
From: SHANMUGAM, SRINIVASAN <[email protected]>
Sent: Wednesday, December 10, 2025 1:53 AM
To: Hung, Alex <[email protected]>; Pillai, Aurabindo <[email protected]>
Cc: [email protected] <[email protected]>; SHANMUGAM, 
SRINIVASAN <[email protected]>; Chen, Robin <[email protected]>; 
Chang, Jack <[email protected]>; Huang, Leon <[email protected]>; Li, Roman 
<[email protected]>; Wentland, Harry <[email protected]>; Chung, ChiaHsuan 
(Tom) <[email protected]>
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: f2429468b582 ("drm/amd/display: Refactor panel replay set dmub cmd flow")
Reported by: Dan Carpenter <[email protected]>
Cc: Robin Chen <[email protected]>
Cc: Jack Chang <[email protected]>
Cc: Leon Huang <[email protected]>
Cc: Alex Hung <[email protected]>
Cc: Aurabindo Pillai <[email protected]>
Cc: Roman Li <[email protected]>
Cc: Harry Wentland <[email protected]>
Cc: Tom Chung <[email protected]>
Signed-off-by: Srinivasan Shanmugam <[email protected]>
---
 .../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.34.1

Reply via email to