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
