The DRM connector core allocates connector indices in the inclusive 0..31 range, but the AMDGPU HDCP workqueue stores per-connector state in arrays sized with AMDGPU_DM_MAX_DISPLAY_INDEX, which is also 31. As a result, connector index 31 can write one element past those arrays.
Resize the HDCP per-connector arrays to cover the full connector ID range and switch the related loops and memset() calls to ARRAY_SIZE() so index 31 is handled safely. Signed-off-by: Pengpeng Hou <[email protected]> --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 18 ++++++++++-------- .../drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h | 8 ++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index eb73bbf8f411..e1ef86674e55 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -291,7 +291,9 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde cancel_delayed_work(&hdcp_w->property_validate_dwork); - for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) { + for (conn_index = 0; + conn_index < ARRAY_SIZE(hdcp_w->encryption_status); + conn_index++) { hdcp_w->encryption_status[conn_index] = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; if (hdcp_w->aconnector[conn_index]) { @@ -338,7 +340,9 @@ static void event_property_update(struct work_struct *work) struct drm_connector *connector; struct drm_connector_state *conn_state; - for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) { + for (conn_index = 0; + conn_index < ARRAY_SIZE(hdcp_work->aconnector); + conn_index++) { aconnector = hdcp_work->aconnector[conn_index]; if (!aconnector) @@ -407,7 +411,8 @@ static void event_property_validate(struct work_struct *work) guard(mutex)(&hdcp_work->mutex); - for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; + for (conn_index = 0; + conn_index < ARRAY_SIZE(hdcp_work->aconnector); conn_index++) { aconnector = hdcp_work->aconnector[conn_index]; @@ -799,11 +804,9 @@ struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, ddc_funcs->atomic_write_poll_read_aux = lp_atomic_write_poll_read_aux; memset(hdcp_work[i].aconnector, 0, - sizeof(struct amdgpu_dm_connector *) * - AMDGPU_DM_MAX_DISPLAY_INDEX); + sizeof(hdcp_work[i].aconnector)); memset(hdcp_work[i].encryption_status, 0, - sizeof(enum mod_hdcp_encryption_status) * - AMDGPU_DM_MAX_DISPLAY_INDEX); + sizeof(hdcp_work[i].encryption_status)); } cp_psp->funcs.update_stream_config = update_config; @@ -826,4 +829,3 @@ struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, return NULL; } - diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h index 4faa344f196e..d0f87d393ce7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h @@ -44,7 +44,7 @@ struct hdcp_workqueue { struct delayed_work callback_dwork; struct delayed_work watchdog_timer_dwork; struct delayed_work property_validate_dwork; - struct amdgpu_dm_connector *aconnector[AMDGPU_DM_MAX_DISPLAY_INDEX]; + struct amdgpu_dm_connector *aconnector[AMDGPU_DM_MAX_DISPLAY_INDEX + 1]; struct mutex mutex; struct mod_hdcp hdcp; @@ -52,7 +52,7 @@ struct hdcp_workqueue { struct mod_hdcp_display display; struct mod_hdcp_link link; - enum mod_hdcp_encryption_status encryption_status[AMDGPU_DM_MAX_DISPLAY_INDEX]; + enum mod_hdcp_encryption_status encryption_status[AMDGPU_DM_MAX_DISPLAY_INDEX + 1]; /* when display is unplugged from mst hub, connctor will be * destroyed within dm_dp_mst_connector_destroy. connector * hdcp perperties, like type, undesired, desired, enabled, @@ -62,9 +62,9 @@ struct hdcp_workqueue { * will be retrieved from hdcp_work within dm_dp_mst_get_modes */ /* un-desired, desired, enabled */ - unsigned int content_protection[AMDGPU_DM_MAX_DISPLAY_INDEX]; + unsigned int content_protection[AMDGPU_DM_MAX_DISPLAY_INDEX + 1]; /* hdcp1.x, hdcp2.x */ - unsigned int hdcp_content_type[AMDGPU_DM_MAX_DISPLAY_INDEX]; + unsigned int hdcp_content_type[AMDGPU_DM_MAX_DISPLAY_INDEX + 1]; uint8_t max_link; -- 2.50.1 (Apple Git-155)
