diff options
author | Stephan Gerhold <stephan@gerhold.net> | 2021-09-13 18:45:56 +0200 |
---|---|---|
committer | Rob Clark <robdclark@chromium.org> | 2021-10-11 17:30:53 -0700 |
commit | efb8a170a367fa898d7848c4e74c1c20222e0d91 (patch) | |
tree | 9f2293e87bc9182d7b410f5ac32a7f0a40947e99 /drivers/gpu | |
parent | 9463b64d1a34fc4d18f9de63f07b2400c86f8da8 (diff) |
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: 9bc95570175a ("drm/msm: Devfreq tuning")
Reported-by: Nikita Travkin <nikita@trvn.ru>
Tested-by: Nikita Travkin <nikita@trvn.ru>
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Link: https://lore.kernel.org/r/20210913164556.16284-1-stephan@gerhold.net
Signed-off-by: Rob Clark <robdclark@chromium.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gpu_devfreq.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 0a1ee20296a2..84e98c07c900 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -151,6 +151,9 @@ void msm_devfreq_active(struct msm_gpu *gpu) unsigned int idle_time; unsigned long target_freq = df->idle_freq; + if (!df->devfreq) + return; + /* * Hold devfreq lock to synchronize with get_dev_status()/ * target() callbacks @@ -186,6 +189,9 @@ void msm_devfreq_idle(struct msm_gpu *gpu) struct msm_gpu_devfreq *df = &gpu->devfreq; unsigned long idle_freq, target_freq = 0; + if (!df->devfreq) + return; + /* * Hold devfreq lock to synchronize with get_dev_status()/ * target() callbacks |