<html><body><p>
<pre>
Hi, Hsin-yi:
On Fri, 2024-02-23 at 13:23 -0800, Hsin-Yi Wang wrote:
>
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> It's possible that mtk_crtc->event is NULL in
> mtk_drm_crtc_finish_page_flip().
>
> pending_needs_vblank value is set by mtk_crtc->event, but in
> mtk_drm_crtc_atomic_flush(), it's is not guarded by the same
> lock in mtk_drm_finish_page_flip(), thus a race condition happens.
>
> Consider the following case:
>
> CPU1 CPU2
> step 1:
> mtk_drm_crtc_atomic_begin()
> mtk_crtc->event is not null,
> step 1:
> mtk_drm_crtc_atomic_flush:
> mtk_drm_crtc_update_config(
> !!mtk_crtc->event)
> step 2:
> mtk_crtc_ddp_irq ->
> mtk_drm_finish_page_flip:
> lock
> mtk_crtc->event set to null,
> pending_needs_vblank set to false
> unlock
> pending_needs_vblank set to true,
>
> step 2:
> mtk_crtc_ddp_irq ->
> mtk_drm_finish_page_flip called
> again,
> pending_needs_vblank is still true
> //null pointer
>
> Instead of guarding the entire mtk_drm_crtc_atomic_flush(), it's more
> efficient to just check if mtk_crtc->event is null before use.
>
> Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
> Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC
> MT8173.")
Reviewed-by: CK Hu <ck.hu@mediatek.com>
> ---
> drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 12 +++++++-----
> 1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index db43f9dff912..d645b85f9721 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -95,11 +95,13 @@ static void mtk_drm_crtc_finish_page_flip(struct
> mtk_drm_crtc *mtk_crtc)
> struct drm_crtc *crtc = &mtk_crtc->base;
> unsigned long flags;
>
> -spin_lock_irqsave(&crtc->dev->event_lock, flags);
> -drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
> -drm_crtc_vblank_put(crtc);
> -mtk_crtc->event = NULL;
> -spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> +if (mtk_crtc->event) {
> +spin_lock_irqsave(&crtc->dev->event_lock, flags);
> +drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
> +drm_crtc_vblank_put(crtc);
> +mtk_crtc->event = NULL;
> +spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> +}
> }
>
> static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
> --
> 2.44.0.rc0.258.g7320e95886-goog
</pre>
</p></body></html><!--type:text--><!--{--><pre>************* MEDIATEK Confidentiality Notice ********************
The information contained in this e-mail message (including any
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be
conveyed only to the designated recipient(s). Any use, dissemination,
distribution, printing, retaining or copying of this e-mail (including its
attachments) by unintended recipient(s) is strictly prohibited and may
be unlawful. If you are not an intended recipient of this e-mail, or believe
that you have received this e-mail in error, please notify the sender
immediately (by replying to this e-mail), delete any and all copies of
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!
</pre><!--}-->