summaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle
diff options
context:
space:
mode:
authorXunlei Pang <pang.xunlei@linaro.org>2015-08-30 23:34:05 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-09-02 21:05:47 -0400
commitabceaa9cded5f059f8c3b3b6f32730084fe5e39f (patch)
tree8f4cfa6f48e5ed6b6eee71ba4d2b7c334a705ba9 /drivers/cpuidle
parent4c1ed5a6079078699128064664913ae7b079648f (diff)
cpuidle/coupled: Add sanity check for safe_state_index
Since we are using cpuidle_driver::safe_state_index directly as the target state index, it is better to add the sanity check at the point of registering the driver. Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r--drivers/cpuidle/coupled.c22
-rw-r--r--drivers/cpuidle/cpuidle.h6
-rw-r--r--drivers/cpuidle/driver.c4
3 files changed, 32 insertions, 0 deletions
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
index 1523e2d745eb..344058f8501a 100644
--- a/drivers/cpuidle/coupled.c
+++ b/drivers/cpuidle/coupled.c
@@ -187,6 +187,28 @@ bool cpuidle_state_is_coupled(struct cpuidle_driver *drv, int state)
187} 187}
188 188
189/** 189/**
190 * cpuidle_coupled_state_verify - check if the coupled states are correctly set.
191 * @drv: struct cpuidle_driver for the platform
192 *
193 * Returns 0 for valid state values, a negative error code otherwise:
194 * * -EINVAL if any coupled state(safe_state_index) is wrongly set.
195 */
196int cpuidle_coupled_state_verify(struct cpuidle_driver *drv)
197{
198 int i;
199
200 for (i = drv->state_count - 1; i >= 0; i--) {
201 if (cpuidle_state_is_coupled(drv, i) &&
202 (drv->safe_state_index == i ||
203 drv->safe_state_index < 0 ||
204 drv->safe_state_index >= drv->state_count))
205 return -EINVAL;
206 }
207
208 return 0;
209}
210
211/**
190 * cpuidle_coupled_set_ready - mark a cpu as ready 212 * cpuidle_coupled_set_ready - mark a cpu as ready
191 * @coupled: the struct coupled that contains the current cpu 213 * @coupled: the struct coupled that contains the current cpu
192 */ 214 */
diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h
index 178c5ad3d568..f87f399b0540 100644
--- a/drivers/cpuidle/cpuidle.h
+++ b/drivers/cpuidle/cpuidle.h
@@ -35,6 +35,7 @@ extern void cpuidle_remove_sysfs(struct cpuidle_device *dev);
35 35
36#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED 36#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
37bool cpuidle_state_is_coupled(struct cpuidle_driver *drv, int state); 37bool cpuidle_state_is_coupled(struct cpuidle_driver *drv, int state);
38int cpuidle_coupled_state_verify(struct cpuidle_driver *drv);
38int cpuidle_enter_state_coupled(struct cpuidle_device *dev, 39int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
39 struct cpuidle_driver *drv, int next_state); 40 struct cpuidle_driver *drv, int next_state);
40int cpuidle_coupled_register_device(struct cpuidle_device *dev); 41int cpuidle_coupled_register_device(struct cpuidle_device *dev);
@@ -46,6 +47,11 @@ bool cpuidle_state_is_coupled(struct cpuidle_driver *drv, int state)
46 return false; 47 return false;
47} 48}
48 49
50static inline int cpuidle_coupled_state_verify(struct cpuidle_driver *drv)
51{
52 return 0;
53}
54
49static inline int cpuidle_enter_state_coupled(struct cpuidle_device *dev, 55static inline int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
50 struct cpuidle_driver *drv, int next_state) 56 struct cpuidle_driver *drv, int next_state)
51{ 57{
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 5db147859b90..389ade4572be 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -227,6 +227,10 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv)
227 if (!drv || !drv->state_count) 227 if (!drv || !drv->state_count)
228 return -EINVAL; 228 return -EINVAL;
229 229
230 ret = cpuidle_coupled_state_verify(drv);
231 if (ret)
232 return ret;
233
230 if (cpuidle_disabled()) 234 if (cpuidle_disabled())
231 return -ENODEV; 235 return -ENODEV;
232 236