Skip to content

Commit d59be57

Browse files
Jessica Zhanglumag
authored andcommitted
drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected
mdp5_get_global_state runs the risk of hitting a -EDEADLK when acquiring the modeset lock, but currently mdp5_pipe_release doesn't check for if an error is returned. Because of this, there is a possibility of mdp5_pipe_release hitting a NULL dereference error. To avoid this, let's have mdp5_pipe_release check if mdp5_get_global_state returns an error and propogate that error. Changes since v1: - Separated declaration and initialization of *new_state to avoid compiler warning - Fixed some spelling mistakes in commit message Changes since v2: - Return 0 in case where hwpipe is NULL as this is considered normal behavior - Added 2nd patch in series to fix a similar NULL dereference issue in mdp5_mixer_release Reported-by: Tomeu Vizoso <[email protected]> Signed-off-by: Jessica Zhang <[email protected]> Fixes: 7907a0d ("drm/msm/mdp5: Use the new private_obj state") Reviewed-by: Rob Clark <[email protected]> Reviewed-by: Dmitry Baryshkov <[email protected]> Patchwork: https://patchwork.freedesktop.org/patch/485179/ Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Baryshkov <[email protected]>
1 parent 2f9b5b3 commit d59be57

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,18 +119,23 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane,
119119
return 0;
120120
}
121121

122-
void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
122+
int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
123123
{
124124
struct msm_drm_private *priv = s->dev->dev_private;
125125
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
126126
struct mdp5_global_state *state = mdp5_get_global_state(s);
127-
struct mdp5_hw_pipe_state *new_state = &state->hwpipe;
127+
struct mdp5_hw_pipe_state *new_state;
128128

129129
if (!hwpipe)
130-
return;
130+
return 0;
131+
132+
if (IS_ERR(state))
133+
return PTR_ERR(state);
134+
135+
new_state = &state->hwpipe;
131136

132137
if (WARN_ON(!new_state->hwpipe_to_plane[hwpipe->idx]))
133-
return;
138+
return -EINVAL;
134139

135140
DBG("%s: release from plane %s", hwpipe->name,
136141
new_state->hwpipe_to_plane[hwpipe->idx]->name);
@@ -141,6 +146,8 @@ void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
141146
}
142147

143148
new_state->hwpipe_to_plane[hwpipe->idx] = NULL;
149+
150+
return 0;
144151
}
145152

146153
void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe)

drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane,
3737
uint32_t caps, uint32_t blkcfg,
3838
struct mdp5_hw_pipe **hwpipe,
3939
struct mdp5_hw_pipe **r_hwpipe);
40-
void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe);
40+
int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe);
4141

4242
struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe,
4343
uint32_t reg_offset, uint32_t caps);

drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,12 +311,24 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
311311
mdp5_state->r_hwpipe = NULL;
312312

313313

314-
mdp5_pipe_release(state->state, old_hwpipe);
315-
mdp5_pipe_release(state->state, old_right_hwpipe);
314+
ret = mdp5_pipe_release(state->state, old_hwpipe);
315+
if (ret)
316+
return ret;
317+
318+
ret = mdp5_pipe_release(state->state, old_right_hwpipe);
319+
if (ret)
320+
return ret;
321+
316322
}
317323
} else {
318-
mdp5_pipe_release(state->state, mdp5_state->hwpipe);
319-
mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
324+
ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe);
325+
if (ret)
326+
return ret;
327+
328+
ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
329+
if (ret)
330+
return ret;
331+
320332
mdp5_state->hwpipe = mdp5_state->r_hwpipe = NULL;
321333
}
322334

0 commit comments

Comments
 (0)