diff options
author | Chen Yu <yu.c.chen@intel.com> | 2015-09-09 06:27:31 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-09-09 16:55:23 -0400 |
commit | 43717aadd2bc87fb10fbf1cd815c1cbae9bb95b3 (patch) | |
tree | a525f784c4a857f55c09d6dc8eee594ea042cffb | |
parent | 953ba9ff77f3d08635712eaeffb218d46889b58a (diff) |
intel_pstate: Fix user input of min/max to legal policy region
In current code, max_perf_pct might be smaller than min_perf_pct
by improper user input:
$ grep . /sys/devices/system/cpu/intel_pstate/m*_perf_pct
/sys/devices/system/cpu/intel_pstate/max_perf_pct:100
/sys/devices/system/cpu/intel_pstate/min_perf_pct:100
$ echo 80 > /sys/devices/system/cpu/intel_pstate/max_perf_pct
$ grep . /sys/devices/system/cpu/intel_pstate/m*_perf_pct
/sys/devices/system/cpu/intel_pstate/max_perf_pct:80
/sys/devices/system/cpu/intel_pstate/min_perf_pct:100
Fix this problem by 2 steps:
1. Normalize the user input to [min_policy, max_policy].
2. Make sure max_perf_pct>=min_perf_pct, suggested by Seiichi Ikarashi.
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
Acked-by: Kristen Carlson Accardi <kristen@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 31d0548638e8..63075cc4a476 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -423,6 +423,8 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, | |||
423 | 423 | ||
424 | limits.max_sysfs_pct = clamp_t(int, input, 0 , 100); | 424 | limits.max_sysfs_pct = clamp_t(int, input, 0 , 100); |
425 | limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); | 425 | limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); |
426 | limits.max_perf_pct = max(limits.min_policy_pct, limits.max_perf_pct); | ||
427 | limits.max_perf_pct = max(limits.min_perf_pct, limits.max_perf_pct); | ||
426 | limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); | 428 | limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); |
427 | 429 | ||
428 | if (hwp_active) | 430 | if (hwp_active) |
@@ -442,6 +444,8 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, | |||
442 | 444 | ||
443 | limits.min_sysfs_pct = clamp_t(int, input, 0 , 100); | 445 | limits.min_sysfs_pct = clamp_t(int, input, 0 , 100); |
444 | limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct); | 446 | limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct); |
447 | limits.min_perf_pct = min(limits.max_policy_pct, limits.min_perf_pct); | ||
448 | limits.min_perf_pct = min(limits.max_perf_pct, limits.min_perf_pct); | ||
445 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); | 449 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); |
446 | 450 | ||
447 | if (hwp_active) | 451 | if (hwp_active) |
@@ -989,12 +993,19 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
989 | 993 | ||
990 | limits.min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq; | 994 | limits.min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq; |
991 | limits.min_policy_pct = clamp_t(int, limits.min_policy_pct, 0 , 100); | 995 | limits.min_policy_pct = clamp_t(int, limits.min_policy_pct, 0 , 100); |
992 | limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct); | ||
993 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); | ||
994 | |||
995 | limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq; | 996 | limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq; |
996 | limits.max_policy_pct = clamp_t(int, limits.max_policy_pct, 0 , 100); | 997 | limits.max_policy_pct = clamp_t(int, limits.max_policy_pct, 0 , 100); |
998 | |||
999 | /* Normalize user input to [min_policy_pct, max_policy_pct] */ | ||
1000 | limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct); | ||
1001 | limits.min_perf_pct = min(limits.max_policy_pct, limits.min_perf_pct); | ||
997 | limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); | 1002 | limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); |
1003 | limits.max_perf_pct = max(limits.min_policy_pct, limits.max_perf_pct); | ||
1004 | |||
1005 | /* Make sure min_perf_pct <= max_perf_pct */ | ||
1006 | limits.min_perf_pct = min(limits.max_perf_pct, limits.min_perf_pct); | ||
1007 | |||
1008 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); | ||
998 | limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); | 1009 | limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); |
999 | 1010 | ||
1000 | if (hwp_active) | 1011 | if (hwp_active) |