Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: Move the mutex_lock to protect the return status of securedisplay command buffer

[Why]
Before we call psp_securedisplay_invoke(), we call
psp_prep_securedisplay_cmd_buf() to prepare and initialize the command
buffer.

However, we didn't use the mutex_lock to protect the status of command
buffer. So when multiple threads are using the command buffer, after
thread A return from psp_securedisplay_invoke() and the command buffer
status is set to SUCCESS, another thread B may call
psp_prep_securedisplay_cmd_buf() and initialize the status to FAILURE
again, and cause Thread A to get a failure return status.

[How]
Move the mutex_lock out of psp_securedisplay_invoke() to its caller to
cover psp_prep_securedisplay_cmd_buf() and the code checking the return
status of command buffer.

Signed-off-by: Alan Liu <HaoPing.Liu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Alan Liu and committed by
Alex Deucher
7117007e 1ed0e176

+13 -4
+5 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 1938 1938 } else 1939 1939 return ret; 1940 1940 1941 + mutex_lock(&psp->securedisplay_context.mutex); 1942 + 1941 1943 psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, 1942 1944 TA_SECUREDISPLAY_COMMAND__QUERY_TA); 1943 1945 1944 1946 ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__QUERY_TA); 1947 + 1948 + mutex_unlock(&psp->securedisplay_context.mutex); 1949 + 1945 1950 if (ret) { 1946 1951 psp_securedisplay_terminate(psp); 1947 1952 /* free securedisplay shared memory */ ··· 1995 1990 ta_cmd_id != TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC) 1996 1991 return -EINVAL; 1997 1992 1998 - mutex_lock(&psp->securedisplay_context.mutex); 1999 - 2000 1993 ret = psp_ta_invoke(psp, ta_cmd_id, &psp->securedisplay_context.context); 2001 - 2002 - mutex_unlock(&psp->securedisplay_context.mutex); 2003 1994 2004 1995 return ret; 2005 1996 }
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c
··· 121 121 122 122 switch (op) { 123 123 case 1: 124 + mutex_lock(&psp->securedisplay_context.mutex); 124 125 psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, 125 126 TA_SECUREDISPLAY_COMMAND__QUERY_TA); 126 127 ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__QUERY_TA); ··· 132 131 else 133 132 psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status); 134 133 } 134 + mutex_unlock(&psp->securedisplay_context.mutex); 135 135 break; 136 136 case 2: 137 + mutex_lock(&psp->securedisplay_context.mutex); 137 138 psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, 138 139 TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC); 139 140 securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = phy_id; ··· 149 146 psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status); 150 147 } 151 148 } 149 + mutex_unlock(&psp->securedisplay_context.mutex); 152 150 break; 153 151 default: 154 152 dev_err(adev->dev, "Invalid input: %s\n", str);
+4
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
··· 123 123 phy_id = crc_rd_wrk->phy_inst; 124 124 spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock); 125 125 126 + mutex_lock(&psp->securedisplay_context.mutex); 127 + 126 128 psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, 127 129 TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC); 128 130 securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = ··· 135 133 psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status); 136 134 } 137 135 } 136 + 137 + mutex_unlock(&psp->securedisplay_context.mutex); 138 138 } 139 139 140 140 static void