Takashi Iwai 08b897
From 0a58d2ae572adaec8d046f8d35b40c2c32ac7468 Mon Sep 17 00:00:00 2001
Takashi Iwai 08b897
From: Javier Martinez Canillas <javierm@redhat.com>
Takashi Iwai 08b897
Date: Tue, 16 Aug 2022 15:46:12 +0200
Takashi Iwai 08b897
Subject: [PATCH] drm/msm: Make .remove and .shutdown HW shutdown consistent
Takashi Iwai 08b897
Git-commit: 0a58d2ae572adaec8d046f8d35b40c2c32ac7468
Takashi Iwai 08b897
Patch-mainline: v6.1-rc1
Takashi Iwai 08b897
References: git-fixes
Takashi Iwai 08b897
Takashi Iwai 08b897
Drivers' .remove and .shutdown callbacks are executed on different code
Takashi Iwai 08b897
paths. The former is called when a device is removed from the bus, while
Takashi Iwai 08b897
the latter is called at system shutdown time to quiesce the device.
Takashi Iwai 08b897
Takashi Iwai 08b897
This means that some overlap exists between the two, because both have to
Takashi Iwai 08b897
take care of properly shutting down the hardware. But currently the logic
Takashi Iwai 08b897
used in these two callbacks isn't consistent in msm drivers, which could
Takashi Iwai 08b897
lead to kernel panic.
Takashi Iwai 08b897
Takashi Iwai 08b897
For example, on .remove the component is deleted and its .unbind callback
Takashi Iwai 08b897
leads to the hardware being shutdown but only if the DRM device has been
Takashi Iwai 08b897
marked as registered.
Takashi Iwai 08b897
Takashi Iwai 08b897
That check doesn't exist in the .shutdown logic and this can lead to the
Takashi Iwai 08b897
driver calling drm_atomic_helper_shutdown() for a DRM device that hasn't
Takashi Iwai 08b897
been properly initialized.
Takashi Iwai 08b897
Takashi Iwai 08b897
A situation like this can happen if drivers for expected sub-devices fail
Takashi Iwai 08b897
to probe, since the .bind callback will never be executed. If that is the
Takashi Iwai 08b897
case, drm_atomic_helper_shutdown() will attempt to take mutexes that are
Takashi Iwai 08b897
only initialized if drm_mode_config_init() is called during a device bind.
Takashi Iwai 08b897
Takashi Iwai 08b897
This bug was attempted to be fixed in commit 623f279c7781 ("drm/msm: fix
Takashi Iwai 08b897
shutdown hook in case GPU components failed to bind"), but unfortunately
Takashi Iwai 08b897
it still happens in some cases as the one mentioned above, i.e:
Takashi Iwai 08b897
Takashi Iwai 08b897
  systemd-shutdown[1]: Powering off.
Takashi Iwai 08b897
  kvm: exiting hardware virtualization
Takashi Iwai 08b897
  platform wifi-firmware.0: Removing from iommu group 12
Takashi Iwai 08b897
  platform video-firmware.0: Removing from iommu group 10
Takashi Iwai 08b897
  ------------[ cut here ]------------
Takashi Iwai 08b897
  WARNING: CPU: 6 PID: 1 at drivers/gpu/drm/drm_modeset_lock.c:317 drm_modeset_lock_all_ctx+0x3c4/0x3d0
Takashi Iwai 08b897
  ...
Takashi Iwai 08b897
  Hardware name: Google CoachZ (rev3+) (DT)
Takashi Iwai 08b897
  pstate: a0400009 (NzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
Takashi Iwai 08b897
  pc : drm_modeset_lock_all_ctx+0x3c4/0x3d0
Takashi Iwai 08b897
  lr : drm_modeset_lock_all_ctx+0x48/0x3d0
Takashi Iwai 08b897
  sp : ffff80000805bb80
Takashi Iwai 08b897
  x29: ffff80000805bb80 x28: ffff327c00128000 x27: 0000000000000000
Takashi Iwai 08b897
  x26: 0000000000000000 x25: 0000000000000001 x24: ffffc95d820ec030
Takashi Iwai 08b897
  x23: ffff327c00bbd090 x22: ffffc95d8215eca0 x21: ffff327c039c5800
Takashi Iwai 08b897
  x20: ffff327c039c5988 x19: ffff80000805bbe8 x18: 0000000000000034
Takashi Iwai 08b897
  x17: 000000040044ffff x16: ffffc95d80cac920 x15: 0000000000000000
Takashi Iwai 08b897
  x14: 0000000000000315 x13: 0000000000000315 x12: 0000000000000000
Takashi Iwai 08b897
  x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
Takashi Iwai 08b897
  x8 : ffff80000805bc28 x7 : 0000000000000000 x6 : 0000000000000000
Takashi Iwai 08b897
  x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
Takashi Iwai 08b897
  x2 : ffff327c00128000 x1 : 0000000000000000 x0 : ffff327c039c59b0
Takashi Iwai 08b897
  Call trace:
Takashi Iwai 08b897
   drm_modeset_lock_all_ctx+0x3c4/0x3d0
Takashi Iwai 08b897
   drm_atomic_helper_shutdown+0x70/0x134
Takashi Iwai 08b897
   msm_drv_shutdown+0x30/0x40
Takashi Iwai 08b897
   platform_shutdown+0x28/0x40
Takashi Iwai 08b897
   device_shutdown+0x148/0x350
Takashi Iwai 08b897
   kernel_power_off+0x38/0x80
Takashi Iwai 08b897
   __do_sys_reboot+0x288/0x2c0
Takashi Iwai 08b897
   __arm64_sys_reboot+0x28/0x34
Takashi Iwai 08b897
   invoke_syscall+0x48/0x114
Takashi Iwai 08b897
   el0_svc_common.constprop.0+0x44/0xec
Takashi Iwai 08b897
   do_el0_svc+0x2c/0xc0
Takashi Iwai 08b897
   el0_svc+0x2c/0x84
Takashi Iwai 08b897
   el0t_64_sync_handler+0x11c/0x150
Takashi Iwai 08b897
   el0t_64_sync+0x18c/0x190
Takashi Iwai 08b897
  ---[ end trace 0000000000000000 ]---
Takashi Iwai 08b897
  Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018
Takashi Iwai 08b897
  Mem abort info:
Takashi Iwai 08b897
    ESR = 0x0000000096000004
Takashi Iwai 08b897
    EC = 0x25: DABT (current EL), IL = 32 bits
Takashi Iwai 08b897
    SET = 0, FnV = 0
Takashi Iwai 08b897
    EA = 0, S1PTW = 0
Takashi Iwai 08b897
    FSC = 0x04: level 0 translation fault
Takashi Iwai 08b897
  Data abort info:
Takashi Iwai 08b897
    ISV = 0, ISS = 0x00000004
Takashi Iwai 08b897
    CM = 0, WnR = 0
Takashi Iwai 08b897
  user pgtable: 4k pages, 48-bit VAs, pgdp=000000010eab1000
Takashi Iwai 08b897
  [0000000000000018] pgd=0000000000000000, p4d=0000000000000000
Takashi Iwai 08b897
  Internal error: Oops: 96000004 [#1] PREEMPT SMP
Takashi Iwai 08b897
  ...
Takashi Iwai 08b897
  Hardware name: Google CoachZ (rev3+) (DT)
Takashi Iwai 08b897
  pstate: a0400009 (NzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
Takashi Iwai 08b897
  pc : ww_mutex_lock+0x28/0x32c
Takashi Iwai 08b897
  lr : drm_modeset_lock_all_ctx+0x1b0/0x3d0
Takashi Iwai 08b897
  sp : ffff80000805bb50
Takashi Iwai 08b897
  x29: ffff80000805bb50 x28: ffff327c00128000 x27: 0000000000000000
Takashi Iwai 08b897
  x26: 0000000000000000 x25: 0000000000000001 x24: 0000000000000018
Takashi Iwai 08b897
  x23: ffff80000805bc10 x22: ffff327c039c5ad8 x21: ffff327c039c5800
Takashi Iwai 08b897
  x20: ffff80000805bbe8 x19: 0000000000000018 x18: 0000000000000034
Takashi Iwai 08b897
  x17: 000000040044ffff x16: ffffc95d80cac920 x15: 0000000000000000
Takashi Iwai 08b897
  x14: 0000000000000315 x13: 0000000000000315 x12: 0000000000000000
Takashi Iwai 08b897
  x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
Takashi Iwai 08b897
  x8 : ffff80000805bc28 x7 : 0000000000000000 x6 : 0000000000000000
Takashi Iwai 08b897
  x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
Takashi Iwai 08b897
  x2 : ffff327c00128000 x1 : 0000000000000000 x0 : 0000000000000018
Takashi Iwai 08b897
  Call trace:
Takashi Iwai 08b897
   ww_mutex_lock+0x28/0x32c
Takashi Iwai 08b897
   drm_modeset_lock_all_ctx+0x1b0/0x3d0
Takashi Iwai 08b897
   drm_atomic_helper_shutdown+0x70/0x134
Takashi Iwai 08b897
   msm_drv_shutdown+0x30/0x40
Takashi Iwai 08b897
   platform_shutdown+0x28/0x40
Takashi Iwai 08b897
   device_shutdown+0x148/0x350
Takashi Iwai 08b897
   kernel_power_off+0x38/0x80
Takashi Iwai 08b897
   __do_sys_reboot+0x288/0x2c0
Takashi Iwai 08b897
   __arm64_sys_reboot+0x28/0x34
Takashi Iwai 08b897
   invoke_syscall+0x48/0x114
Takashi Iwai 08b897
   el0_svc_common.constprop.0+0x44/0xec
Takashi Iwai 08b897
   do_el0_svc+0x2c/0xc0
Takashi Iwai 08b897
   el0_svc+0x2c/0x84
Takashi Iwai 08b897
   el0t_64_sync_handler+0x11c/0x150
Takashi Iwai 08b897
   el0t_64_sync+0x18c/0x190
Takashi Iwai 08b897
  Code: aa0103f4 d503201f d2800001 aa0103e3 (c8e37c02)
Takashi Iwai 08b897
  ---[ end trace 0000000000000000 ]---
Takashi Iwai 08b897
  Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
Takashi Iwai 08b897
  Kernel Offset: 0x495d77c00000 from 0xffff800008000000
Takashi Iwai 08b897
  PHYS_OFFSET: 0xffffcd8500000000
Takashi Iwai 08b897
  CPU features: 0x800,00c2a015,19801c82
Takashi Iwai 08b897
  Memory Limit: none
Takashi Iwai 08b897
  ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
Takashi Iwai 08b897
Takashi Iwai 08b897
Fixes: 9d5cbf5fe46e ("drm/msm: add shutdown support for display platform_driver")
Takashi Iwai 08b897
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Takashi Iwai 08b897
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Takashi Iwai 08b897
Link: https://patchwork.freedesktop.org/patch/msgid/20220816134612.916527-1-javierm@redhat.com
Takashi Iwai 08b897
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 08b897
Takashi Iwai 08b897
---
Takashi Iwai 08b897
 drivers/gpu/drm/msm/msm_drv.c |   13 +++++++++----
Takashi Iwai 08b897
 1 file changed, 9 insertions(+), 4 deletions(-)
Takashi Iwai 08b897
Takashi Iwai 08b897
--- a/drivers/gpu/drm/msm/msm_drv.c
Takashi Iwai 08b897
+++ b/drivers/gpu/drm/msm/msm_drv.c
Takashi Iwai 08b897
@@ -1358,10 +1358,15 @@ static void msm_pdev_shutdown(struct pla
Takashi Iwai 08b897
 	struct drm_device *drm = platform_get_drvdata(pdev);
Takashi Iwai 08b897
 	struct msm_drm_private *priv = drm ? drm->dev_private : NULL;
Takashi Iwai 08b897
 
Takashi Iwai 08b897
-	if (!priv || !priv->kms)
Takashi Iwai 08b897
-		return;
Takashi Iwai 08b897
-
Takashi Iwai 08b897
-	drm_atomic_helper_shutdown(drm);
Takashi Iwai 08b897
+	/*
Takashi Iwai 08b897
+	 * Shutdown the hw if we're far enough along where things might be on.
Takashi Iwai 08b897
+	 * If we run this too early, we'll end up panicking in any variety of
Takashi Iwai 08b897
+	 * places. Since we don't register the drm device until late in
Takashi Iwai 08b897
+	 * msm_drm_init, drm_dev->registered is used as an indicator that the
Takashi Iwai 08b897
+	 * shutdown will be successful.
Takashi Iwai 08b897
+	 */
Takashi Iwai 08b897
+	if (drm && drm->registered)
Takashi Iwai 08b897
+		drm_atomic_helper_shutdown(drm);
Takashi Iwai 08b897
 }
Takashi Iwai 08b897
 
Takashi Iwai 08b897
 static const struct of_device_id dt_match[] = {