Skip to content

Commit

Permalink
cpufreq: Initialize policy before making it available for others to use
Browse files Browse the repository at this point in the history
Policy must be fully initialized before it is being made available
for use by others. Otherwise cpufreq_cpu_get() would be able to grab
a half initialized policy structure that might not have affected_cpus
(for example) populated. Then, anybody accessing those fields will get
a wrong value and that will lead to unpredictable results.

In order to fix this, do all the necessary initialization before we
make the policy structure available via cpufreq_cpu_get(). That will
guarantee that any code accessing fields of the policy will get
correct data from them.

Reported-by: Saravana Kannan <[email protected]>
Signed-off-by: Viresh Kumar <[email protected]>
[rjw: Changelog]
Signed-off-by: Rafael J. Wysocki <[email protected]>
  • Loading branch information
vireshk authored and rafaeljw committed Mar 6, 2014
1 parent 999976e commit 5a7e56a
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,20 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
goto err_set_policy_cpu;
}

/* related cpus should atleast have policy->cpus */
cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);

/*
* affected cpus must always be the one, which are online. We aren't
* managing offline cpus here.
*/
cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);

if (!frozen) {
policy->user_policy.min = policy->min;
policy->user_policy.max = policy->max;
}

write_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_cpu(j, policy->cpus)
per_cpu(cpufreq_cpu_data, j) = policy;
Expand Down Expand Up @@ -1162,20 +1176,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
}
}

/* related cpus should atleast have policy->cpus */
cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);

/*
* affected cpus must always be the one, which are online. We aren't
* managing offline cpus here.
*/
cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);

if (!frozen) {
policy->user_policy.min = policy->min;
policy->user_policy.max = policy->max;
}

blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
CPUFREQ_START, policy);

Expand Down

0 comments on commit 5a7e56a

Please sign in to comment.