Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24a315ee authored by Kishore Sri venkata Ganesh Bolisetty's avatar Kishore Sri venkata Ganesh Bolisetty
Browse files

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: default avatarKishore Sri venkata Ganesh Bolisetty <bsrivenk@codeaurora.org>
parent b38b5109
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -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,