summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-11-01 19:11:03 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-11-05 17:06:21 +1100
commit978d7eb31d44de34a7f71e04ed4158f3f854688d (patch)
treeaed6b90715df7b2f44a69ac948a0af70a4427143 /arch
parentf1167fb318f0ff0bcb9cbb57bb6d16ad450f0cfb (diff)
downloadlinux-3.10-978d7eb31d44de34a7f71e04ed4158f3f854688d.tar.gz
linux-3.10-978d7eb31d44de34a7f71e04ed4158f3f854688d.tar.bz2
linux-3.10-978d7eb31d44de34a7f71e04ed4158f3f854688d.zip
powerpc: Avoid giving out RTC dates below EPOCH
Doing so causes xtime to be negative which crashes the timekeeping code in funny ways when doing suspend/resume Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/time.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 92dc844299b..a136a11c490 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -777,7 +777,7 @@ int update_persistent_clock(struct timespec now)
return ppc_md.set_rtc_time(&tm);
}
-void read_persistent_clock(struct timespec *ts)
+static void __read_persistent_clock(struct timespec *ts)
{
struct rtc_time tm;
static int first = 1;
@@ -800,10 +800,23 @@ void read_persistent_clock(struct timespec *ts)
return;
}
ppc_md.get_rtc_time(&tm);
+
ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
+void read_persistent_clock(struct timespec *ts)
+{
+ __read_persistent_clock(ts);
+
+ /* Sanitize it in case real time clock is set below EPOCH */
+ if (ts->tv_sec < 0) {
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ }
+
+}
+
/* clocksource code */
static cycle_t rtc_read(struct clocksource *cs)
{