Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [Medium] drm/mediatek: data race on ddp_comp array in mtk_crtc_mode_valid
--

commit 932f98864769c15d84bbf97b7de7de8b563c5923
Author: zoan37 <[email protected]>

drm/mediatek: mtk_crtc: Pick the connector route on every CRTC enable

mtk_crtc_update_output() only picks the output component of a CRTC
with connector routes when connectors_changed is set in the commit that
enables the CRTC. But connectors_changed only says that the connectors
changed in that commit, not since the CRTC was last enabled. A connector
can be attached to (or moved to) the CRTC while it is inactive, and the
later commit that only sets ACTIVE then has active_changed but not
connectors_changed:

- If the CRTC had never been enabled, the route slot is still NULL and
  mtk_crtc_ddp_hw_init() dereferences it (mtk_ddp_comp_clk_enable()
  and so on).
- If the CRTC was driven through another route before, e.g. a CRTC
  shared by an HDMI bridge on DSI and a DisplayPort output that is
  switched off (DPMS) while the monitor moves from one to the other,
  the pipeline is set up for the old output.

update_output() only runs from atomic_enable and the lookup is a short
loop over the routes, so do it on every enable.

> diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_crtc.c
> index 704931b369b6f..0bfd17f682826 100644
> --- a/drivers/gpu/drm/mediatek/mtk_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
> @@ -695,9 +695,6 @@ static void mtk_crtc_update_output(struct drm_crtc *crtc,
>       struct mtk_drm_private *priv;
>       unsigned int encoder_mask = crtc_state->encoder_mask;
>  
> -     if (!crtc_state->connectors_changed)
> -             return;
> -

[Severity: Medium]
Does removing this guard expose a data race on the ddp_comp array in
mtk_crtc_mode_valid()?

A non-blocking atomic commit executes mtk_crtc_atomic_enable() asynchronously
via the commit_tail worker, which does not hold dev->mode_config.mutex.

This calls mtk_crtc_update_output(), which modifies the array using plain
non-atomic assignment:

mtk_crtc_update_output()
        mtk_crtc->ddp_comp[mtk_crtc->ddp_comp_nr - 1] = comp;

Concurrently, unprivileged userspace can issue DRM_IOCTL_MODE_GETCONNECTOR,
which acquires mode_config.mutex and invokes
drm_helper_probe_single_connector_modes().

This iterates over all possible CRTCs and calls mtk_crtc_mode_valid(), which
reads the entire ddp_comp array without READ_ONCE():

mtk_crtc_mode_valid()
        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
                status = mtk_ddp_comp_mode_valid(mtk_crtc->ddp_comp[i], mode);

Could this lead to undefined behavior, KCSAN splats, or a crash if compiler
optimization splits the pointer read in the inlined mtk_ddp_comp_mode_valid()
function?

>       if (!mtk_crtc->num_conn_routes)
>               return;
>

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=3

Reply via email to