From 24a315ee3cb8561400307b1262f838921c11ce0f Mon Sep 17 00:00:00 2001 From: Kishore Sri venkata Ganesh Bolisetty Date: Mon, 6 Apr 2020 11:59:24 -0700 Subject: [PATCH] soc: qcom: msm_perf: fix invalid usuage of cpumask set/get API used for freq updates are using an invalid cpumask variables which may potentially lead to stack corruption. Change-Id: I25fdc5dc25550c39bc81a2efbd55d16679d37e19 Signed-off-by: Kishore Sri venkata Ganesh Bolisetty --- drivers/soc/qcom/msm_performance.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/soc/qcom/msm_performance.c b/drivers/soc/qcom/msm_performance.c index ac0d4e480b54..5b81ad4fea2d 100644 --- a/drivers/soc/qcom/msm_performance.c +++ b/drivers/soc/qcom/msm_performance.c @@ -56,6 +56,9 @@ static unsigned int aggr_top_load; static unsigned int top_load[CLUSTER_MAX]; static unsigned int curr_cap[CLUSTER_MAX]; +static cpumask_var_t limit_mask_min; +static cpumask_var_t limit_mask_max; + /*******************************sysfs start************************************/ static int set_cpu_min_freq(const char *buf, const struct kernel_param *kp) { @@ -65,7 +68,6 @@ static int set_cpu_min_freq(const char *buf, const struct kernel_param *kp) struct cpu_status *i_cpu_stats; struct cpufreq_policy policy; struct freq_qos_request *req; - cpumask_var_t limit_mask; while ((cp = strpbrk(cp + 1, " :"))) ntokens++; @@ -75,7 +77,7 @@ static int set_cpu_min_freq(const char *buf, const struct kernel_param *kp) return -EINVAL; cp = buf; - cpumask_clear(limit_mask); + cpumask_clear(limit_mask_min); for (i = 0; i < ntokens; i += 2) { if (sscanf(cp, "%u:%u", &cpu, &val) != 2) return -EINVAL; @@ -85,7 +87,7 @@ static int set_cpu_min_freq(const char *buf, const struct kernel_param *kp) i_cpu_stats = &per_cpu(msm_perf_cpu_stats, cpu); i_cpu_stats->min = val; - cpumask_set_cpu(cpu, limit_mask); + cpumask_set_cpu(cpu, limit_mask_min); cp = strnchr(cp, strlen(cp), ' '); cp++; @@ -99,7 +101,7 @@ static int set_cpu_min_freq(const char *buf, const struct kernel_param *kp) * in the cluster */ get_online_cpus(); - for_each_cpu(i, limit_mask) { + for_each_cpu(i, limit_mask_min) { i_cpu_stats = &per_cpu(msm_perf_cpu_stats, i); if (cpufreq_get_policy(&policy, i)) @@ -112,7 +114,7 @@ static int set_cpu_min_freq(const char *buf, const struct kernel_param *kp) } for_each_cpu(j, policy.related_cpus) - cpumask_clear_cpu(j, limit_mask); + cpumask_clear_cpu(j, limit_mask_min); } put_online_cpus(); @@ -146,7 +148,7 @@ static int set_cpu_max_freq(const char *buf, const struct kernel_param *kp) struct cpu_status *i_cpu_stats; struct cpufreq_policy policy; struct freq_qos_request *req; - cpumask_var_t limit_mask; + while ((cp = strpbrk(cp + 1, " :"))) ntokens++; @@ -156,7 +158,7 @@ static int set_cpu_max_freq(const char *buf, const struct kernel_param *kp) return -EINVAL; cp = buf; - cpumask_clear(limit_mask); + cpumask_clear(limit_mask_max); for (i = 0; i < ntokens; i += 2) { if (sscanf(cp, "%u:%u", &cpu, &val) != 2) return -EINVAL; @@ -166,14 +168,14 @@ static int set_cpu_max_freq(const char *buf, const struct kernel_param *kp) i_cpu_stats = &per_cpu(msm_perf_cpu_stats, cpu); i_cpu_stats->max = val; - cpumask_set_cpu(cpu, limit_mask); + cpumask_set_cpu(cpu, limit_mask_max); cp = strnchr(cp, strlen(cp), ' '); cp++; } get_online_cpus(); - for_each_cpu(i, limit_mask) { + for_each_cpu(i, limit_mask_max) { i_cpu_stats = &per_cpu(msm_perf_cpu_stats, i); if (cpufreq_get_policy(&policy, i)) continue; @@ -185,7 +187,7 @@ static int set_cpu_max_freq(const char *buf, const struct kernel_param *kp) } for_each_cpu(j, policy.related_cpus) - cpumask_clear_cpu(j, limit_mask); + cpumask_clear_cpu(j, limit_mask_max); } put_online_cpus(); @@ -499,6 +501,14 @@ static int __init msm_performance_init(void) } } + if (!alloc_cpumask_var(&limit_mask_min, GFP_KERNEL)) + return -ENOMEM; + + if (!alloc_cpumask_var(&limit_mask_max, GFP_KERNEL)) { + free_cpumask_var(limit_mask_min); + return -ENOMEM; + } + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE, "msm_performance_cpu_hotplug", hotplug_notify,