Hi Maxime On Fri, 29 Jan 2021 at 16:07, Maxime Ripard <maxime@xxxxxxxxxx> wrote: > > Commit 0a038c1c29a7 ("drm/vc4: Move LBM creation out of > vc4_plane_mode_set()") changed the LBM allocation logic from first > allocating the LBM memory for the plane to running mode_set, > adding a gap in the LBM, and then running the dlist allocation filling > that gap. > > The gap was introduced by incrementing the dlist array index, but was > never checking whether or not we were over the array length, leading > eventually to memory corruptions if we ever crossed this limit. > > vc4_dlist_write had that logic though, and was reallocating a larger > dlist array when reaching the end of the buffer. Let's share the logic > between both functions. > > Cc: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxx> > Cc: Eric Anholt <eric@xxxxxxxxxx> > Fixes: 0a038c1c29a7 ("drm/vc4: Move LBM creation out of vc4_plane_mode_set()") > Signed-off-by: Maxime Ripard <maxime@xxxxxxxxxx> Looks good. Reviewed-by: Dave Stevenson <dave.stevenson@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/vc4/vc4_plane.c | 18 ++++++++++++++---- > 1 file changed, 14 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c > index b5586c92bfe5..3d33fe3dacea 100644 > --- a/drivers/gpu/drm/vc4/vc4_plane.c > +++ b/drivers/gpu/drm/vc4/vc4_plane.c > @@ -227,7 +227,7 @@ static void vc4_plane_reset(struct drm_plane *plane) > __drm_atomic_helper_plane_reset(plane, &vc4_state->base); > } > > -static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) > +static void vc4_dlist_counter_increment(struct vc4_plane_state *vc4_state) > { > if (vc4_state->dlist_count == vc4_state->dlist_size) { > u32 new_size = max(4u, vc4_state->dlist_count * 2); > @@ -242,7 +242,15 @@ static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) > vc4_state->dlist_size = new_size; > } > > - vc4_state->dlist[vc4_state->dlist_count++] = val; > + vc4_state->dlist_count++; > +} > + > +static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) > +{ > + unsigned int idx = vc4_state->dlist_count; > + > + vc4_dlist_counter_increment(vc4_state); > + vc4_state->dlist[idx] = val; > } > > /* Returns the scl0/scl1 field based on whether the dimensions need to > @@ -1057,8 +1065,10 @@ static int vc4_plane_mode_set(struct drm_plane *plane, > * be set when calling vc4_plane_allocate_lbm(). > */ > if (vc4_state->y_scaling[0] != VC4_SCALING_NONE || > - vc4_state->y_scaling[1] != VC4_SCALING_NONE) > - vc4_state->lbm_offset = vc4_state->dlist_count++; > + vc4_state->y_scaling[1] != VC4_SCALING_NONE) { > + vc4_state->lbm_offset = vc4_state->dlist_count; > + vc4_dlist_counter_increment(vc4_state); > + } > > if (num_planes > 1) { > /* Emit Cb/Cr as channel 0 and Y as channel > -- > 2.29.2 > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel