On Fri, 18 Feb 2022, Ville Syrjala <ville.syrjala@xxxxxxxxxxxxxxx> wrote: > From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > struct drm_display_mode embeds a list head, so overwriting > the full struct with another one will corrupt the list > (if the destination mode is on a list). Use drm_mode_copy() > instead which explicitly preserves the list head of > the destination mode. > > Even if we know the destination mode is not on any list > using drm_mode_copy() seems decent as it sets a good > example. Bad examples of not using it might eventually > get copied into code where preserving the list head > actually matters. > > Obviously one case not covered here is when the mode > itself is embedded in a larger structure and the whole > structure is copied. But if we are careful when copying > into modes embedded in structures I think we can be a > little more reassured that bogus list heads haven't been > propagated in. > > @is_mode_copy@ > @@ > drm_mode_copy(...) > { > ... > } > > @depends on !is_mode_copy@ > struct drm_display_mode *mode; > expression E, S; > @@ > ( > - *mode = E > + drm_mode_copy(mode, &E) > | > - memcpy(mode, E, S) > + drm_mode_copy(mode, E) > ) > > @depends on !is_mode_copy@ > struct drm_display_mode mode; > expression E; > @@ > ( > - mode = E > + drm_mode_copy(&mode, &E) > | > - memcpy(&mode, E, S) > + drm_mode_copy(&mode, E) > ) > > @@ > struct drm_display_mode *mode; > @@ > - &*mode > + mode > > Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Reviewed-by: Jani Nikula <jani.nikula@xxxxxxxxx> > --- > drivers/gpu/drm/i915/display/intel_display.c | 15 ++++++++++----- > 1 file changed, 10 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c > index 74c5a99ab276..661e36435793 100644 > --- a/drivers/gpu/drm/i915/display/intel_display.c > +++ b/drivers/gpu/drm/i915/display/intel_display.c > @@ -5506,8 +5506,10 @@ intel_crtc_copy_uapi_to_hw_state_modeset(struct intel_atomic_state *state, > > crtc_state->hw.enable = crtc_state->uapi.enable; > crtc_state->hw.active = crtc_state->uapi.active; > - crtc_state->hw.mode = crtc_state->uapi.mode; > - crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode; > + drm_mode_copy(&crtc_state->hw.mode, > + &crtc_state->uapi.mode); > + drm_mode_copy(&crtc_state->hw.adjusted_mode, > + &crtc_state->uapi.adjusted_mode); > crtc_state->hw.scaling_filter = crtc_state->uapi.scaling_filter; > > intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc); > @@ -5584,9 +5586,12 @@ copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state, > memset(&slave_crtc_state->hw, 0, sizeof(slave_crtc_state->hw)); > slave_crtc_state->hw.enable = master_crtc_state->hw.enable; > slave_crtc_state->hw.active = master_crtc_state->hw.active; > - slave_crtc_state->hw.mode = master_crtc_state->hw.mode; > - slave_crtc_state->hw.pipe_mode = master_crtc_state->hw.pipe_mode; > - slave_crtc_state->hw.adjusted_mode = master_crtc_state->hw.adjusted_mode; > + drm_mode_copy(&slave_crtc_state->hw.mode, > + &master_crtc_state->hw.mode); > + drm_mode_copy(&slave_crtc_state->hw.pipe_mode, > + &master_crtc_state->hw.pipe_mode); > + drm_mode_copy(&slave_crtc_state->hw.adjusted_mode, > + &master_crtc_state->hw.adjusted_mode); > slave_crtc_state->hw.scaling_filter = master_crtc_state->hw.scaling_filter; > > copy_bigjoiner_crtc_state_nomodeset(state, slave_crtc); -- Jani Nikula, Intel Open Source Graphics Center