From: Aleksandr Mishin amishin@t-argos.ru
stable inclusion from stable-v6.6.33 commit f84b9b25d045e67a7eee5e73f21278c8ab06713c category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IA74DQ
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit cf7de25878a1f4508c69dc9f6819c21ba177dbfe ]
cppc_cpufreq_get_rate() and hisi_cppc_cpufreq_get_rate() can be called from different places with various parameters. So cpufreq_cpu_get() can return null as 'policy' in some circumstances. Fix this bug by adding null return check.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: a28b2bfc099c ("cppc_cpufreq: replace per-cpu data array with a list") Signed-off-by: Aleksandr Mishin amishin@t-argos.ru Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org
Conflicts: drivers/cpufreq/cppc_cpufreq.c [Context conflict] Signed-off-by: ZhangPeng zhangpeng362@huawei.com Signed-off-by: Liu Mingrui liumingrui@huawei.com --- drivers/cpufreq/cppc_cpufreq.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 66e8c850e6f2..eb4e27a4d192 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -878,10 +878,15 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) { struct fb_ctr_pair fb_ctrs = { .cpu = cpu, }; struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - struct cppc_cpudata *cpu_data = policy->driver_data; + struct cppc_cpudata *cpu_data; u64 delivered_perf; int ret;
+ if (!policy) + return -ENODEV; + + cpu_data = policy->driver_data; + cpufreq_cpu_put(policy);
if (cpu_has_amu_feat(cpu)) @@ -961,10 +966,15 @@ static struct cpufreq_driver cppc_cpufreq_driver = { static unsigned int hisi_cppc_cpufreq_get_rate(unsigned int cpu) { struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - struct cppc_cpudata *cpu_data = policy->driver_data; + struct cppc_cpudata *cpu_data; u64 desired_perf; int ret;
+ if (!policy) + return -ENODEV; + + cpu_data = policy->driver_data; + cpufreq_cpu_put(policy);
ret = cppc_get_desired_perf(cpu, &desired_perf);