aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen Yu <yu.c.chen@intel.com>2015-09-09 06:27:31 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-09-09 16:55:23 -0400
commit43717aadd2bc87fb10fbf1cd815c1cbae9bb95b3 (patch)
treea525f784c4a857f55c09d6dc8eee594ea042cffb
parent953ba9ff77f3d08635712eaeffb218d46889b58a (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.c17
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)