Skip to content

Commit e07ed98

Browse files
Bhawanpreet Lakhagregkh
authored andcommitted
drm/amd/display: Change HDCP update sequence for DM
[ Upstream commit 393e83484839970e4975dfa1f0666f939a6f3e3d ] Refactor the sequence in hdcp_update_display() to use mod_hdcp_update_display(). Previous sequence: - remove()->add() This Sequence was used to update the display, (mod_hdcp_update_display didn't exist at the time). This meant for any hdcp updates (type changes, enable/disable) we would remove, reconstruct, and add. This leads to unnecessary calls to psp eventually New Sequence using mod_hdcp_update_display(): - add() once when stream is enabled - use update() for all updates The update function checks for prev == new states and will not unnecessarily end up calling psp via add/remove. Reviewed-by: Qingqing Zhuo <[email protected]> Acked-by: Tom Chung <[email protected]> Signed-off-by: Bhawanpreet Lakha <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Stable-dep-of: be593d9d91c5 ("drm/amd/display: Fix slab-use-after-free in hdcp") Signed-off-by: Sasha Levin <[email protected]>
1 parent e56b740 commit e07ed98

File tree

1 file changed

+38
-42
lines changed

1 file changed

+38
-42
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -168,53 +168,45 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
168168
bool enable_encryption)
169169
{
170170
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
171-
struct mod_hdcp_display *display = &hdcp_work[link_index].display;
172-
struct mod_hdcp_link *link = &hdcp_work[link_index].link;
173-
struct mod_hdcp_display_query query;
171+
struct mod_hdcp_link_adjustment link_adjust;
172+
struct mod_hdcp_display_adjustment display_adjust;
174173
unsigned int conn_index = aconnector->base.index;
175174

176175
mutex_lock(&hdcp_w->mutex);
177176
hdcp_w->aconnector[conn_index] = aconnector;
178177

179-
query.display = NULL;
180-
mod_hdcp_query_display(&hdcp_w->hdcp, aconnector->base.index, &query);
181-
182-
if (query.display) {
183-
memcpy(display, query.display, sizeof(struct mod_hdcp_display));
184-
mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
185-
186-
hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;
187-
188-
if (enable_encryption) {
189-
/* Explicitly set the saved SRM as sysfs call will be after
190-
* we already enabled hdcp (s3 resume case)
191-
*/
192-
if (hdcp_work->srm_size > 0)
193-
psp_set_srm(hdcp_work->hdcp.config.psp.handle, hdcp_work->srm,
194-
hdcp_work->srm_size,
195-
&hdcp_work->srm_version);
196-
197-
display->adjust.disable = MOD_HDCP_DISPLAY_NOT_DISABLE;
198-
if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0) {
199-
hdcp_w->link.adjust.hdcp1.disable = 0;
200-
hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;
201-
} else if (content_type == DRM_MODE_HDCP_CONTENT_TYPE1) {
202-
hdcp_w->link.adjust.hdcp1.disable = 1;
203-
hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_1;
204-
}
178+
memset(&link_adjust, 0, sizeof(link_adjust));
179+
memset(&display_adjust, 0, sizeof(display_adjust));
205180

206-
schedule_delayed_work(&hdcp_w->property_validate_dwork,
207-
msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS));
208-
} else {
209-
display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
210-
hdcp_w->encryption_status[conn_index] = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
211-
cancel_delayed_work(&hdcp_w->property_validate_dwork);
181+
if (enable_encryption) {
182+
/* Explicitly set the saved SRM as sysfs call will be after we already enabled hdcp
183+
* (s3 resume case)
184+
*/
185+
if (hdcp_work->srm_size > 0)
186+
psp_set_srm(hdcp_work->hdcp.config.psp.handle, hdcp_work->srm,
187+
hdcp_work->srm_size,
188+
&hdcp_work->srm_version);
189+
190+
display_adjust.disable = MOD_HDCP_DISPLAY_NOT_DISABLE;
191+
192+
link_adjust.auth_delay = 2;
193+
194+
if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0) {
195+
link_adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;
196+
} else if (content_type == DRM_MODE_HDCP_CONTENT_TYPE1) {
197+
link_adjust.hdcp1.disable = 1;
198+
link_adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_1;
212199
}
213200

214-
display->state = MOD_HDCP_DISPLAY_ACTIVE;
201+
schedule_delayed_work(&hdcp_w->property_validate_dwork,
202+
msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS));
203+
} else {
204+
display_adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
205+
hdcp_w->encryption_status[conn_index] = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
206+
cancel_delayed_work(&hdcp_w->property_validate_dwork);
215207
}
216208

217-
mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
209+
mod_hdcp_update_display(&hdcp_w->hdcp, conn_index, &link_adjust, &display_adjust, &hdcp_w->output);
218210

219211
process_output(hdcp_w);
220212
mutex_unlock(&hdcp_w->mutex);
@@ -521,7 +513,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
521513
int link_index = aconnector->dc_link->link_index;
522514
struct mod_hdcp_display *display = &hdcp_work[link_index].display;
523515
struct mod_hdcp_link *link = &hdcp_work[link_index].link;
524-
struct drm_connector_state *conn_state;
516+
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
525517
struct dc_sink *sink = NULL;
526518
bool link_is_hdcp14 = false;
527519

@@ -563,17 +555,21 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
563555
display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
564556
link->adjust.auth_delay = 3;
565557
link->adjust.hdcp1.disable = 0;
566-
conn_state = aconnector->base.state;
558+
hdcp_w->encryption_status[display->index] = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
567559

568560
DRM_DEBUG_DRIVER("[HDCP_DM] display %d, CP %d, type %d\n", aconnector->base.index,
569561
(!!aconnector->base.state) ?
570562
aconnector->base.state->content_protection : -1,
571563
(!!aconnector->base.state) ?
572564
aconnector->base.state->hdcp_content_type : -1);
573565

574-
if (conn_state)
575-
hdcp_update_display(hdcp_work, link_index, aconnector,
576-
conn_state->hdcp_content_type, false);
566+
mutex_lock(&hdcp_w->mutex);
567+
568+
mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
569+
570+
process_output(hdcp_w);
571+
mutex_unlock(&hdcp_w->mutex);
572+
577573
}
578574

579575
/**

0 commit comments

Comments
 (0)