[Freedreno] [v2] drm/msm: add null checks for drm device to avoid crash during probe defer
Dmitry Baryshkov
dmitry.baryshkov at linaro.org
Wed Jun 15 12:23:44 UTC 2022
On 03/06/2022 12:42, Vinod Polimera wrote:
> During probe defer, drm device is not initialized and an external
> trigger to shutdown is trying to clean up drm device leading to crash.
> Add checks to avoid drm device cleanup in such cases.
>
> BUG: unable to handle kernel NULL pointer dereference at virtual
> address 00000000000000b8
>
> Call trace:
>
> drm_atomic_helper_shutdown+0x44/0x144
> msm_pdev_shutdown+0x2c/0x38
> platform_shutdown+0x2c/0x38
> device_shutdown+0x158/0x210
> kernel_restart_prepare+0x40/0x4c
> kernel_restart+0x20/0x6c
> __arm64_sys_reboot+0x194/0x23c
> invoke_syscall+0x50/0x13c
> el0_svc_common+0xa0/0x17c
> do_el0_svc_compat+0x28/0x34
> el0_svc_compat+0x20/0x70
> el0t_32_sync_handler+0xa8/0xcc
> el0t_32_sync+0x1a8/0x1ac
>
> Changes in v2:
> - Add fixes tag.
>
> Fixes: 623f279c778 ("drm/msm: fix shutdown hook in case GPU components failed to bind")
> Signed-off-by: Vinod Polimera <quic_vpolimer at quicinc.com>
> ---
> drivers/gpu/drm/msm/msm_drv.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 4448536..d62ac66 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -142,6 +142,9 @@ static void msm_irq_uninstall(struct drm_device *dev)
> struct msm_drm_private *priv = dev->dev_private;
> struct msm_kms *kms = priv->kms;
>
> + if (!irq_has_action(kms->irq))
> + return;
As a second thought I'd still prefer a variable here. irq_has_action
would check that there is _any_ IRQ handler for this IRQ. While we do
not have anybody sharing this IRQ, I'd prefer to be clear here, that we
do not want to uninstall our IRQ handler rather than any IRQ handler.
> +
> kms->funcs->irq_uninstall(kms);
> if (kms->irq_requested)
> free_irq(kms->irq, dev);
> @@ -259,6 +262,7 @@ static int msm_drm_uninit(struct device *dev)
>
> ddev->dev_private = NULL;
> drm_dev_put(ddev);
> + priv->dev = NULL;
>
> destroy_workqueue(priv->wq);
>
> @@ -1167,7 +1171,7 @@ void msm_drv_shutdown(struct platform_device *pdev)
> struct msm_drm_private *priv = platform_get_drvdata(pdev);
> struct drm_device *drm = priv ? priv->dev : NULL;
>
> - if (!priv || !priv->kms)
> + if (!priv || !priv->kms || !drm)
> return;
>
> drm_atomic_helper_shutdown(drm);
--
With best wishes
Dmitry
More information about the Freedreno
mailing list