aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorpang.xunlei <pang.xunlei@linaro.org>2014-10-08 03:03:34 -0400
committerJohn Stultz <john.stultz@linaro.org>2014-11-21 14:59:56 -0500
commit6067dc5a8c2b1b57e67eaf1125db1d63c1ed6361 (patch)
treefc089bc25bc69fa089146f163f3aa9383c71b879 /kernel/time
parentfd866e2b116b01d42428491899fe9925c42c121c (diff)
time: Avoid possible NTP adjustment mult overflow.
Ideally, __clocksource_updatefreq_scale, selects the largest shift value possible for a clocksource. This results in the mult memember of struct clocksource being particularly large, although not so large that NTP would adjust the clock to cause it to overflow. That said, nothing actually prohibits an overflow from occuring, its just that it "shouldn't" occur. So while very unlikely, and so far never observed, the value of (cs->mult+cs->maxadj) may have a chance to reach very near 0xFFFFFFFF, so there is a possibility it may overflow when doing NTP positive adjustment See the following detail: When NTP slewes the clock, kernel goes through update_wall_time()->...->timekeeping_apply_adjustment(): tk->tkr.mult += mult_adj; Since there is no guard against it, its possible tk->tkr.mult may overflow during this operation. This patch avoids any possible mult overflow by judging the overflow case before adding mult_adj to mult, also adds the WARNING message when capturing such case. Signed-off-by: pang.xunlei <pang.xunlei@linaro.org> [jstultz: Reworded commit message] Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/timekeeping.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index ec1791fae965..cad61b3f6bea 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1332,6 +1332,12 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
1332 * 1332 *
1333 * XXX - TODO: Doc ntp_error calculation. 1333 * XXX - TODO: Doc ntp_error calculation.
1334 */ 1334 */
1335 if (tk->tkr.mult + mult_adj < mult_adj) {
1336 /* NTP adjustment caused clocksource mult overflow */
1337 WARN_ON_ONCE(1);
1338 return;
1339 }
1340
1335 tk->tkr.mult += mult_adj; 1341 tk->tkr.mult += mult_adj;
1336 tk->xtime_interval += interval; 1342 tk->xtime_interval += interval;
1337 tk->tkr.xtime_nsec -= offset; 1343 tk->tkr.xtime_nsec -= offset;