meson_drv_bind_master() does not free resources in the order they are allocated. This can lead to crashes such as: Unable to handle kernel NULL pointer dereference at virtual address 00000000000000c8 [...] Hardware name: Beelink GT-King Pro (DT) pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : meson_dw_hdmi_unbind+0x10/0x24 [meson_dw_hdmi] lr : component_unbind+0x38/0x60 [...] Call trace: meson_dw_hdmi_unbind+0x10/0x24 [meson_dw_hdmi] component_unbind+0x38/0x60 component_unbind_all+0xb8/0xc4 meson_drv_bind_master+0x1ec/0x514 [meson_drm] meson_drv_bind+0x14/0x20 [meson_drm] try_to_bring_up_aggregate_device+0xa8/0x160 __component_add+0xb8/0x1a8 component_add+0x14/0x20 meson_dw_hdmi_probe+0x1c/0x28 [meson_dw_hdmi] platform_probe+0x68/0xdc really_probe+0xc0/0x39c __driver_probe_device+0x7c/0x14c driver_probe_device+0x3c/0x120 __driver_attach+0xc4/0x200 bus_for_each_dev+0x78/0xd8 driver_attach+0x24/0x30 bus_add_driver+0x110/0x240 driver_register+0x68/0x124 __platform_driver_register+0x24/0x30 meson_dw_hdmi_platform_driver_init+0x20/0x1000 [meson_dw_hdmi] do_one_initcall+0x50/0x1bc do_init_module+0x54/0x1fc load_module+0x788/0x884 init_module_from_file+0x88/0xd4 __arm64_sys_finit_module+0x248/0x340 invoke_syscall+0x48/0x104 el0_svc_common.constprop.0+0x40/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x30/0xcc el0t_64_sync_handler+0x120/0x12c el0t_64_sync+0x190/0x194
Clean up resources in the error path in the same order and under the same conditions as they were allocated to fix this. Reported-by: Furkan Kardame <f.kard...@manjaro.org> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com> --- This issue was reported off-list so I'm unable to provide a link to the report. I'm not sure which Fixes tag fits best. My preference so far is Fixes: 6a044642988b ("drm/meson: fix unbind path if HDMI fails to bind") but I'll happily take other suggestions as well. drivers/gpu/drm/meson/meson_drv.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 81d2ee37e773..031686fd4104 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -314,35 +314,35 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) dev_err(drm->dev, "Couldn't bind all components\n"); /* Do not try to unbind */ has_components = false; - goto exit_afbcd; + goto cvbs_encoder_remove; } } ret = meson_encoder_hdmi_probe(priv); if (ret) - goto exit_afbcd; + goto unbind_components; if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { ret = meson_encoder_dsi_probe(priv); if (ret) - goto exit_afbcd; + goto hdmi_encoder_remove; } ret = meson_plane_create(priv); if (ret) - goto exit_afbcd; + goto dsi_encoder_remove; ret = meson_overlay_create(priv); if (ret) - goto exit_afbcd; + goto dsi_encoder_remove; ret = meson_crtc_create(priv); if (ret) - goto exit_afbcd; + goto dsi_encoder_remove; ret = request_irq(priv->vsync_irq, meson_irq, 0, drm->driver->name, drm); if (ret) - goto exit_afbcd; + goto dsi_encoder_remove; drm_mode_config_reset(drm); @@ -360,6 +360,16 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) uninstall_irq: free_irq(priv->vsync_irq, drm); +dsi_encoder_remove: + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + meson_encoder_dsi_remove(priv); +hdmi_encoder_remove: + meson_encoder_hdmi_remove(priv); +unbind_components: + if (has_components) + component_unbind_all(dev, drm); +cvbs_encoder_remove: + meson_encoder_cvbs_remove(priv); exit_afbcd: if (priv->afbcd.ops) priv->afbcd.ops->exit(priv); @@ -374,13 +384,6 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) free_drm: drm_dev_put(drm); - meson_encoder_dsi_remove(priv); - meson_encoder_hdmi_remove(priv); - meson_encoder_cvbs_remove(priv); - - if (has_components) - component_unbind_all(dev, drm); - return ret; } -- 2.49.0