aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorYang Yingliang <yangyingliang@huawei.com>2015-10-31 18:20:55 +0800
committerThomas Gleixner <tglx@linutronix.de>2015-12-19 15:59:57 +0100
commit1f45f1f33c8c8b96722dbc5e6b7acf74eaa721f7 (patch)
treebc1df835ae7e7c64889961f3330cd7dc0e5448d7 /kernel/time
parentMerge branch 'fortglx/4.5/time' of https://git.linaro.org/people/john.stultz/linux into timers/core (diff)
downloadlinux-dev-1f45f1f33c8c8b96722dbc5e6b7acf74eaa721f7.tar.xz
linux-dev-1f45f1f33c8c8b96722dbc5e6b7acf74eaa721f7.zip
clocksource: Make clocksource validation work for all clocksources
The clocksource validation which makes sure that the newly read value is not smaller than the last value only works if the clocksource mask is 64bit, i.e. the counter is 64bit wide. But we want to use that mechanism also for clocksources which are less than 64bit wide. So instead of checking whether bit 63 is set, we check whether the most significant bit of the clocksource mask is set in the delta result. If it is set, we return 0. [ tglx: Simplified the implementation, added a comment and massaged the commit message ] Suggested-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Cc: <linux-arm-kernel@lists.infradead.org> Link: http://lkml.kernel.org/r/56349607.6070708@huawei.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/timekeeping_internal.h6
1 files changed, 5 insertions, 1 deletions
diff --git a/kernel/time/timekeeping_internal.h b/kernel/time/timekeeping_internal.h
index e20466ffc208..5be76270ec4a 100644
--- a/kernel/time/timekeeping_internal.h
+++ b/kernel/time/timekeeping_internal.h
@@ -17,7 +17,11 @@ static inline cycle_t clocksource_delta(cycle_t now, cycle_t last, cycle_t mask)
{
cycle_t ret = (now - last) & mask;
- return (s64) ret > 0 ? ret : 0;
+ /*
+ * Prevent time going backwards by checking the MSB of mask in
+ * the result. If set, return 0.
+ */
+ return ret & ~(mask >> 1) ? 0 : ret;
}
#else
static inline cycle_t clocksource_delta(cycle_t now, cycle_t last, cycle_t mask)