aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
diff options
context:
space:
mode:
authorWayne Lin <Wayne.Lin@amd.com>2021-03-06 18:37:33 +0800
committerAlex Deucher <alexander.deucher@amd.com>2021-03-23 23:32:50 -0400
commitcd95ef0097ca1c88c31aaa278d58a5ab45605e74 (patch)
treeba65d461f22c777412a1c59e5a0f9f27814f255f /drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
parentdrm/amd/display: Fix typo for helpers function name (diff)
downloadwireguard-linux-cd95ef0097ca1c88c31aaa278d58a5ab45605e74.tar.xz
wireguard-linux-cd95ef0097ca1c88c31aaa278d58a5ab45605e74.zip
drm/amd/display: Fix secure display lock problems
[Why] Find out few locks problems while doing secure display. They are following few parts: 1. crc_rd_work_lock in amdgpu_dm_crtc_handle_crc_window_irq() should also use spin_lock_irqsave instead of spin_lock_irq. 2. In crc_win_update_set(), crc_rd_work_lock should be grabbed after obtaining lock event_lock. Otherwise, will cause deadlock by conflicting the lock order in amdgpu_dm_crtc_handle_crc_window_irq() 3. flush_work() in crc_win_update_set() is no need and will cause deadlock since amdgpu_dm_crtc_notify_ta_to_read() also tries to grab lock crc_rd_work_lock. [How] Fix above problems. Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Wayne Lin <Wayne.Lin@amd.com> Reviewed-by: Solomon Chiu <Solomon.Chiu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 6d839d3fb6a3..b8644f49e0f2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -2695,14 +2695,12 @@ static int crc_win_update_set(void *data, u64 val)
struct crc_rd_work *crc_rd_wrk = adev->dm.crc_rd_wrk;
if (val) {
- spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
spin_lock_irq(&adev_to_drm(adev)->event_lock);
+ spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
if (crc_rd_wrk && crc_rd_wrk->crtc) {
old_crtc = crc_rd_wrk->crtc;
old_acrtc = to_amdgpu_crtc(old_crtc);
- flush_work(&adev->dm.crc_rd_wrk->notify_ta_work);
}
-
new_acrtc = to_amdgpu_crtc(new_crtc);
if (old_crtc && old_crtc != new_crtc) {
@@ -2720,8 +2718,8 @@ static int crc_win_update_set(void *data, u64 val)
new_acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
crc_rd_wrk->crtc = new_crtc;
}
- spin_unlock_irq(&adev_to_drm(adev)->event_lock);
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
+ spin_unlock_irq(&adev_to_drm(adev)->event_lock);
}
return 0;