Skip to content

Commit a7bfb2a

Browse files
quic-bjorandelumag
authored andcommitted
drm/msm/dp: Drop aux devices together with DP controller
Using devres to depopulate the aux bus made sure that upon a probe deferral the EDP panel device would be destroyed and recreated upon next attempt. But the struct device which the devres is tied to is the DPUs (drm_dev->dev), which may be happen after the DP controller is torn down. Indications of this can be seen in the commonly seen EDID-hexdump full of zeros in the log, or the occasional/rare KASAN fault where the panel's attempt to read the EDID information causes a use after free on DP resources. It's tempting to move the devres to the DP controller's struct device, but the resources used by the device(s) on the aux bus are explicitly torn down in the error path. The KASAN-reported use-after-free also remains, as the DP aux "module" explicitly frees its devres-allocated memory in this code path. As such, explicitly depopulate the aux bus in the error path, and in the component unbind path, to avoid these issues. Fixes: 2b57f72 ("drm/msm/dp: fix aux-bus EP lifetime") Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Patchwork: https://patchwork.freedesktop.org/patch/542163/ Link: https://lore.kernel.org/r/20230612220106.1884039-1-quic_bjorande@quicinc.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
1 parent fda5209 commit a7bfb2a

1 file changed

Lines changed: 3 additions & 11 deletions

File tree

drivers/gpu/drm/msm/dp/dp_display.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ static void dp_display_unbind(struct device *dev, struct device *master,
326326

327327
kthread_stop(dp->ev_tsk);
328328

329+
of_dp_aux_depopulate_bus(dp->aux);
330+
329331
dp_power_client_deinit(dp->power);
330332
dp_unregister_audio_driver(dev, dp->audio);
331333
dp_aux_unregister(dp->aux);
@@ -1479,11 +1481,6 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
14791481
}
14801482
}
14811483

1482-
static void of_dp_aux_depopulate_bus_void(void *data)
1483-
{
1484-
of_dp_aux_depopulate_bus(data);
1485-
}
1486-
14871484
static int dp_display_get_next_bridge(struct msm_dp *dp)
14881485
{
14891486
int rc;
@@ -1511,12 +1508,6 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
15111508
of_node_put(aux_bus);
15121509
if (rc)
15131510
goto error;
1514-
1515-
rc = devm_add_action_or_reset(dp->drm_dev->dev,
1516-
of_dp_aux_depopulate_bus_void,
1517-
dp_priv->aux);
1518-
if (rc)
1519-
goto error;
15201511
} else if (dp->is_edp) {
15211512
DRM_ERROR("eDP aux_bus not found\n");
15221513
return -ENODEV;
@@ -1540,6 +1531,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
15401531

15411532
error:
15421533
if (dp->is_edp) {
1534+
of_dp_aux_depopulate_bus(dp_priv->aux);
15431535
dp_display_host_phy_exit(dp_priv);
15441536
dp_display_host_deinit(dp_priv);
15451537
}

0 commit comments

Comments
 (0)