Commit efb8a170 authored by Stephan Gerhold's avatar Stephan Gerhold Committed by Rob Clark

drm/msm: Fix devfreq NULL pointer dereference on a3xx

There is no devfreq on a3xx at the moment since gpu_busy is not
implemented. This means that msm_devfreq_init() will return early
and the entire devfreq setup is skipped.

However, msm_devfreq_active() and msm_devfreq_idle() are still called
unconditionally later, causing a NULL pointer dereference:

  Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
  Internal error: Oops: 96000004 [#1] PREEMPT SMP
  CPU: 0 PID: 133 Comm: ring0 Not tainted 5.15.0-rc1 #4
  Hardware name: Longcheer L8150 (DT)
  pc : mutex_lock_io+0x2bc/0x2f0
  lr : msm_devfreq_active+0x3c/0xe0 [msm]
  Call trace:
   mutex_lock_io+0x2bc/0x2f0
   msm_gpu_submit+0x164/0x180 [msm]
   msm_job_run+0x54/0xe0 [msm]
   drm_sched_main+0x2b0/0x4a0 [gpu_sched]
   kthread+0x154/0x160
   ret_from_fork+0x10/0x20

Fix this by adding a check in msm_devfreq_active/idle() which ensures
that devfreq was actually initialized earlier.

Fixes: 9bc95570 ("drm/msm: Devfreq tuning")
Reported-by: default avatarNikita Travkin <nikita@trvn.ru>
Tested-by: default avatarNikita Travkin <nikita@trvn.ru>
Signed-off-by: default avatarStephan Gerhold <stephan@gerhold.net>
Link: https://lore.kernel.org/r/20210913164556.16284-1-stephan@gerhold.netSigned-off-by: default avatarRob Clark <robdclark@chromium.org>
parent 9463b64d
...@@ -151,6 +151,9 @@ void msm_devfreq_active(struct msm_gpu *gpu) ...@@ -151,6 +151,9 @@ void msm_devfreq_active(struct msm_gpu *gpu)
unsigned int idle_time; unsigned int idle_time;
unsigned long target_freq = df->idle_freq; unsigned long target_freq = df->idle_freq;
if (!df->devfreq)
return;
/* /*
* Hold devfreq lock to synchronize with get_dev_status()/ * Hold devfreq lock to synchronize with get_dev_status()/
* target() callbacks * target() callbacks
...@@ -186,6 +189,9 @@ void msm_devfreq_idle(struct msm_gpu *gpu) ...@@ -186,6 +189,9 @@ void msm_devfreq_idle(struct msm_gpu *gpu)
struct msm_gpu_devfreq *df = &gpu->devfreq; struct msm_gpu_devfreq *df = &gpu->devfreq;
unsigned long idle_freq, target_freq = 0; unsigned long idle_freq, target_freq = 0;
if (!df->devfreq)
return;
/* /*
* Hold devfreq lock to synchronize with get_dev_status()/ * Hold devfreq lock to synchronize with get_dev_status()/
* target() callbacks * target() callbacks
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment