When releasing a timeslot there is a slight chance we may end up
with the wrong payload mask due to overflow if the delayed_destroy_work
ends up coming into play after a DP 2.1 monitor gets disconnected
which causes vcpi to become 0 then we try to make the payload =
~BIT(vcpi - 1) which is a negative shift.

Signed-off-by: Suraj Kandpal <[email protected]>
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 64e5c176d5cc..3cf1eafcfcb5 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4531,6 +4531,7 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
        struct drm_dp_mst_atomic_payload *payload;
        struct drm_connector_state *old_conn_state, *new_conn_state;
        bool update_payload = true;
+       int bit;
 
        old_conn_state = drm_atomic_get_old_connector_state(state, 
port->connector);
        if (!old_conn_state->crtc)
@@ -4572,7 +4573,8 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
        if (!payload->delete) {
                payload->pbn = 0;
                payload->delete = true;
-               topology_state->payload_mask &= ~BIT(payload->vcpi - 1);
+               bit = payload->vcpi ? payload->vcpi - 1 : 0;
+               topology_state->payload_mask &= ~BIT(bit);
        }
 
        return 0;
-- 
2.34.1

Reply via email to