linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc
@ 2014-11-18 11:15 pang.xunlei
  2014-11-18 11:15 ` [RFC PATCH v3 1/5] time: Provide y2038 safe do_settimeofday() replacement pang.xunlei
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: pang.xunlei @ 2014-11-18 11:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: rtc-linux, Thomas Gleixner, Alessandro Zummo, John Stultz,
	Arnd Bergmann, pang.xunlei

On 32bit systems, the kernel uses a 32bit signed time_t value
for seconds since 1970-01-01:00:00:00. This will overflow at
2038-01-19 03:14:08, and is widely known as the y2038 problem.

To address this, the plan is to create 64bit internal interfaces
which are 2038 safe, mark the unsafe versions as deprecated and 
then convert subsystems one by one over to the new interfaces.
Once all users are converted, the deprecated internal functions
will be removed.

NOTE: In some cases, there are issues with 32bit values that are
unsigned, and thus become y2106 issues. Since its somewhat simpler
to unify the time types, we'll try to convert those usage to 64bit
where it can be easily done. In those cases where a fix would be 
overly complicated, we'll simply explicitly mark the limitation.

This patchset introduces the 64bit interfaces needed to convert
the drivers/rtc subsystem, and to keep it relatively short some
patches to demonstrate how the conversion will be done. If the 
feedback is positive on this series, we'll provide the full 
conversion series as well.

pang.xunlei (5):
  time: Provide y2038 safe do_settimeofday() replacement
  time: Provide y2038 safe timekeeping_inject_sleeptime() replacement
  time: Provide y2038 safe mktime() replacement
  rtc/lib: Provide y2038 safe rtc_tm_to_time()/rtc_time_to_tm()
    replacement
  rtc/mc13xxx: Eliminate time problems

 drivers/rtc/rtc-lib.c       |   38 ++++++++++++++++++++------------------
 drivers/rtc/rtc-mc13xxx.c   |   25 +++++++++++--------------
 include/linux/rtc.h         |   21 +++++++++++++++++++--
 include/linux/time.h        |   17 ++++++++++++++---
 include/linux/timekeeping.h |   34 ++++++++++++++++++++++++++++++++--
 kernel/time/time.c          |   20 ++++++++------------
 kernel/time/timekeeping.c   |   29 +++++++++++++----------------
 7 files changed, 117 insertions(+), 67 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFC PATCH v3 1/5] time: Provide y2038 safe do_settimeofday() replacement
  2014-11-18 11:15 [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc pang.xunlei
@ 2014-11-18 11:15 ` pang.xunlei
  2014-11-18 11:15 ` [RFC PATCH v3 2/5] time: Provide y2038 safe timekeeping_inject_sleeptime() replacement pang.xunlei
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: pang.xunlei @ 2014-11-18 11:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: rtc-linux, Thomas Gleixner, Alessandro Zummo, John Stultz,
	Arnd Bergmann, pang.xunlei

The kernel uses 32-bit signed value(time_t) for seconds elapsed
1970-01-01:00:00:00, thus it will overflow at 2038-01-19 03:14:08
on 32-bit systems. This is widely known as the y2038 problem.

As part of addressing "y2038 problem" for in-kernel uses, this patch
adds safe do_settimeofday64() using timespec64.

After this patch, do_settimeofday() is deprecated and all its call
sites will be fixed using do_settimeofday64(), after that it can be
removed.

Signed-off-by: pang.xunlei <pang.xunlei@linaro.org>
---
 include/linux/timekeeping.h |   21 ++++++++++++++++++++-
 kernel/time/timekeeping.c   |   19 +++++++++----------
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 1caa6b0..071ad7e 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -10,7 +10,7 @@ extern int timekeeping_suspended;
  * Get and set timeofday
  */
 extern void do_gettimeofday(struct timeval *tv);
-extern int do_settimeofday(const struct timespec *tv);
+extern int do_settimeofday64(const struct timespec64 *ts);
 extern int do_sys_settimeofday(const struct timespec *tv,
 			       const struct timezone *tz);
 
@@ -33,6 +33,14 @@ extern int __getnstimeofday64(struct timespec64 *tv);
 extern void getnstimeofday64(struct timespec64 *tv);
 
 #if BITS_PER_LONG == 64
+/**
+ * Deprecated. Use do_settimeofday64().
+ */
+static inline int do_settimeofday(const struct timespec *ts)
+{
+	return do_settimeofday64(ts);
+}
+
 static inline int __getnstimeofday(struct timespec *ts)
 {
 	return __getnstimeofday64(ts);
@@ -54,6 +62,17 @@ static inline void ktime_get_real_ts(struct timespec *ts)
 }
 
 #else
+/**
+ * Deprecated. Use do_settimeofday64().
+ */
+static inline int do_settimeofday(const struct timespec *ts)
+{
+	struct timespec64 ts64;
+
+	ts64 = timespec_to_timespec64(*ts);
+	return do_settimeofday64(&ts64);
+}
+
 static inline int __getnstimeofday(struct timespec *ts)
 {
 	struct timespec64 ts64;
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index ec1791f..1d33550 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -703,18 +703,18 @@ void do_gettimeofday(struct timeval *tv)
 EXPORT_SYMBOL(do_gettimeofday);
 
 /**
- * do_settimeofday - Sets the time of day
- * @tv:		pointer to the timespec variable containing the new time
+ * do_settimeofday64 - Sets the time of day.
+ * @ts:     pointer to the timespec64 variable containing the new time
  *
  * Sets the time of day to the new time and update NTP and notify hrtimers
  */
-int do_settimeofday(const struct timespec *tv)
+int do_settimeofday64(const struct timespec64 *ts)
 {
 	struct timekeeper *tk = &tk_core.timekeeper;
-	struct timespec64 ts_delta, xt, tmp;
+	struct timespec64 ts_delta, xt;
 	unsigned long flags;
 
-	if (!timespec_valid_strict(tv))
+	if (!timespec64_valid_strict(ts))
 		return -EINVAL;
 
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
@@ -723,13 +723,12 @@ int do_settimeofday(const struct timespec *tv)
 	timekeeping_forward_now(tk);
 
 	xt = tk_xtime(tk);
-	ts_delta.tv_sec = tv->tv_sec - xt.tv_sec;
-	ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec;
+	ts_delta.tv_sec = ts->tv_sec - xt.tv_sec;
+	ts_delta.tv_nsec = ts->tv_nsec - xt.tv_nsec;
 
 	tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));
 
-	tmp = timespec_to_timespec64(*tv);
-	tk_set_xtime(tk, &tmp);
+	tk_set_xtime(tk, ts);
 
 	timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
 
@@ -741,7 +740,7 @@ int do_settimeofday(const struct timespec *tv)
 
 	return 0;
 }
-EXPORT_SYMBOL(do_settimeofday);
+EXPORT_SYMBOL(do_settimeofday64);
 
 /**
  * timekeeping_inject_offset - Adds or subtracts from the current time.
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC PATCH v3 2/5] time: Provide y2038 safe timekeeping_inject_sleeptime() replacement
  2014-11-18 11:15 [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc pang.xunlei
  2014-11-18 11:15 ` [RFC PATCH v3 1/5] time: Provide y2038 safe do_settimeofday() replacement pang.xunlei
@ 2014-11-18 11:15 ` pang.xunlei
  2014-11-18 12:05   ` Thomas Gleixner
  2014-11-18 11:15 ` [RFC PATCH v3 3/5] time: Provide y2038 safe mktime() replacement pang.xunlei
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: pang.xunlei @ 2014-11-18 11:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: rtc-linux, Thomas Gleixner, Alessandro Zummo, John Stultz,
	Arnd Bergmann, pang.xunlei

As part of addressing "y2038 problem" for in-kernel uses, this
patch adds timekeeping_inject_sleeptime64() using timespec64.

After this patch, timekeeping_inject_sleeptime() is deprecated
and all its call sites will be fixed using the new interface,
after that it can be removed.

NOTE: timekeeping_inject_sleeptime() is safe actually, but we
want to eliminate timespec eventually, so comes this patch.

Signed-off-by: pang.xunlei <pang.xunlei@linaro.org>
---
 include/linux/timekeeping.h |   13 ++++++++++++-
 kernel/time/timekeeping.c   |   10 ++++------
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 071ad7e..6d76c65 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -201,7 +201,18 @@ static inline void timekeeping_clocktai(struct timespec *ts)
 /*
  * RTC specific
  */
-extern void timekeeping_inject_sleeptime(struct timespec *delta);
+extern void timekeeping_inject_sleeptime64(struct timespec64 *delta);
+
+/**
+ * Deprecated. Use timekeeping_inject_sleeptime64().
+ */
+static inline void timekeeping_inject_sleeptime(struct timespec *delta)
+{
+	struct timespec64 delta64;
+
+	delta64 = timespec_to_timespec64(*delta);
+	timekeeping_inject_sleeptime64(&delta64);
+}
 
 /*
  * PPS accessor
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 1d33550..d37f775 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1067,8 +1067,8 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
 }
 
 /**
- * timekeeping_inject_sleeptime - Adds suspend interval to timeekeeping values
- * @delta: pointer to a timespec delta value
+ * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
+ * @delta: pointer to a timespec64 delta value
  *
  * This hook is for architectures that cannot support read_persistent_clock
  * because their RTC/persistent clock is only accessible when irqs are enabled.
@@ -1076,10 +1076,9 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
  * This function should only be called by rtc_resume(), and allows
  * a suspend offset to be injected into the timekeeping values.
  */
-void timekeeping_inject_sleeptime(struct timespec *delta)
+void timekeeping_inject_sleeptime64(struct timespec64 *delta)
 {
 	struct timekeeper *tk = &tk_core.timekeeper;
-	struct timespec64 tmp;
 	unsigned long flags;
 
 	/*
@@ -1094,8 +1093,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
 
 	timekeeping_forward_now(tk);
 
-	tmp = timespec_to_timespec64(*delta);
-	__timekeeping_inject_sleeptime(tk, &tmp);
+	__timekeeping_inject_sleeptime(tk, delta);
 
 	timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC PATCH v3 3/5] time: Provide y2038 safe mktime() replacement
  2014-11-18 11:15 [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc pang.xunlei
  2014-11-18 11:15 ` [RFC PATCH v3 1/5] time: Provide y2038 safe do_settimeofday() replacement pang.xunlei
  2014-11-18 11:15 ` [RFC PATCH v3 2/5] time: Provide y2038 safe timekeeping_inject_sleeptime() replacement pang.xunlei
@ 2014-11-18 11:15 ` pang.xunlei
  2014-11-18 11:15 ` [RFC PATCH v3 4/5] rtc/lib: Provide y2038 safe rtc_tm_to_time()/rtc_time_to_tm() replacement pang.xunlei
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: pang.xunlei @ 2014-11-18 11:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: rtc-linux, Thomas Gleixner, Alessandro Zummo, John Stultz,
	Arnd Bergmann, pang.xunlei

As part of addressing "y2038 problem" for in-kernel uses, this
patch adds safe mktime64() using time64_t.

After this patch, mktime() is deprecated and all its call sites
will be fixed using mktime64(), after that it can be removed.

Signed-off-by: pang.xunlei <pang.xunlei@linaro.org>
---
 include/linux/time.h |   17 ++++++++++++++---
 kernel/time/time.c   |   20 ++++++++------------
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/include/linux/time.h b/include/linux/time.h
index 8c42cf8..203c2ad 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -39,9 +39,20 @@ static inline int timeval_compare(const struct timeval *lhs, const struct timeva
 	return lhs->tv_usec - rhs->tv_usec;
 }
 
-extern unsigned long mktime(const unsigned int year, const unsigned int mon,
-			    const unsigned int day, const unsigned int hour,
-			    const unsigned int min, const unsigned int sec);
+extern time64_t mktime64(const unsigned int year, const unsigned int mon,
+			const unsigned int day, const unsigned int hour,
+			const unsigned int min, const unsigned int sec);
+
+/**
+ * Deprecated. Use mktime64().
+ */
+static inline unsigned long mktime(const unsigned int year,
+			const unsigned int mon, const unsigned int day,
+			const unsigned int hour, const unsigned int min,
+			const unsigned int sec)
+{
+	return mktime64(year, mon, day, hour, min, sec);
+}
 
 extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
 
diff --git a/kernel/time/time.c b/kernel/time/time.c
index a9ae20f..65015ff 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -304,7 +304,9 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran)
 }
 EXPORT_SYMBOL(timespec_trunc);
 
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+/*
+ * mktime64 - Converts date to seconds.
+ * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
  * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
  *
@@ -314,15 +316,10 @@ EXPORT_SYMBOL(timespec_trunc);
  * -year/100+year/400 terms, and add 10.]
  *
  * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines where long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
  */
-unsigned long
-mktime(const unsigned int year0, const unsigned int mon0,
-       const unsigned int day, const unsigned int hour,
-       const unsigned int min, const unsigned int sec)
+time64_t mktime64(const unsigned int year0, const unsigned int mon0,
+		const unsigned int day, const unsigned int hour,
+		const unsigned int min, const unsigned int sec)
 {
 	unsigned int mon = mon0, year = year0;
 
@@ -332,15 +329,14 @@ mktime(const unsigned int year0, const unsigned int mon0,
 		year -= 1;
 	}
 
-	return ((((unsigned long)
+	return ((((time64_t)
 		  (year/4 - year/100 + year/400 + 367*mon/12 + day) +
 		  year*365 - 719499
 	    )*24 + hour /* now have hours */
 	  )*60 + min /* now have minutes */
 	)*60 + sec; /* finally seconds */
 }
-
-EXPORT_SYMBOL(mktime);
+EXPORT_SYMBOL(mktime64);
 
 /**
  * set_normalized_timespec - set timespec sec and nsec parts and normalize
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC PATCH v3 4/5] rtc/lib: Provide y2038 safe rtc_tm_to_time()/rtc_time_to_tm() replacement
  2014-11-18 11:15 [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc pang.xunlei
                   ` (2 preceding siblings ...)
  2014-11-18 11:15 ` [RFC PATCH v3 3/5] time: Provide y2038 safe mktime() replacement pang.xunlei
@ 2014-11-18 11:15 ` pang.xunlei
  2014-11-18 11:15 ` [RFC PATCH v3 5/5] rtc/mc13xxx: Eliminate time problems pang.xunlei
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: pang.xunlei @ 2014-11-18 11:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: rtc-linux, Thomas Gleixner, Alessandro Zummo, John Stultz,
	Arnd Bergmann, pang.xunlei

As part of addressing "y2038 problem" for in-kernel uses, this patch
adds safe rtc_tm_to_time64()/rtc_time64_to_tm() respectively using
time64_t.

After this patch, rtc_tm_to_time() is deprecated and all its call
sites will be fixed using corresponding safe versions, it can be
removed when having no users. Also change rtc_tm_to_time64() to
return time64_t directly instead of just as a parameter like
rtc_tm_to_time() does.

After this patch, rtc_time_to_tm() is deprecated and all its call
sites will be fixed using corresponding safe versions, it can be
removed when having no users.

In addition, change rtc_tm_to_ktime() and rtc_ktime_to_tm() to use
the safe version in passing.

Signed-off-by: pang.xunlei <pang.xunlei@linaro.org>
---
 drivers/rtc/rtc-lib.c |   38 ++++++++++++++++++++------------------
 include/linux/rtc.h   |   21 +++++++++++++++++++--
 2 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index c4cf057..e6bfb9c 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -45,16 +45,20 @@ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year)
 }
 EXPORT_SYMBOL(rtc_year_days);
 
+
 /*
+ * rtc_time_to_tm64 - Converts time64_t to rtc_time.
  * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
  */
-void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
+void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
 {
 	unsigned int month, year;
+	unsigned long secs;
 	int days;
 
-	days = time / 86400;
-	time -= (unsigned int) days * 86400;
+	/* time must be positive */
+	days = div_s64(time, 86400);
+	secs = time - (unsigned int) days * 86400;
 
 	/* day of the week, 1970-01-01 was a Thursday */
 	tm->tm_wday = (days + 4) % 7;
@@ -81,14 +85,14 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
 	tm->tm_mon = month;
 	tm->tm_mday = days + 1;
 
-	tm->tm_hour = time / 3600;
-	time -= tm->tm_hour * 3600;
-	tm->tm_min = time / 60;
-	tm->tm_sec = time - tm->tm_min * 60;
+	tm->tm_hour = secs / 3600;
+	secs -= tm->tm_hour * 3600;
+	tm->tm_min = secs / 60;
+	tm->tm_sec = secs - tm->tm_min * 60;
 
 	tm->tm_isdst = 0;
 }
-EXPORT_SYMBOL(rtc_time_to_tm);
+EXPORT_SYMBOL(rtc_time64_to_tm);
 
 /*
  * Does the rtc_time represent a valid date/time?
@@ -109,24 +113,22 @@ int rtc_valid_tm(struct rtc_time *tm)
 EXPORT_SYMBOL(rtc_valid_tm);
 
 /*
+ * rtc_tm_to_time64 - Converts rtc_time to time64_t.
  * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
  */
-int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
+time64_t rtc_tm_to_time64(struct rtc_time *tm)
 {
-	*time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+	return mktime64(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
 			tm->tm_hour, tm->tm_min, tm->tm_sec);
-	return 0;
 }
-EXPORT_SYMBOL(rtc_tm_to_time);
+EXPORT_SYMBOL(rtc_tm_to_time64);
 
 /*
  * Convert rtc_time to ktime
  */
 ktime_t rtc_tm_to_ktime(struct rtc_time tm)
 {
-	time_t time;
-	rtc_tm_to_time(&tm, &time);
-	return ktime_set(time, 0);
+	return ktime_set(rtc_tm_to_time64(&tm), 0);
 }
 EXPORT_SYMBOL_GPL(rtc_tm_to_ktime);
 
@@ -135,14 +137,14 @@ EXPORT_SYMBOL_GPL(rtc_tm_to_ktime);
  */
 struct rtc_time rtc_ktime_to_tm(ktime_t kt)
 {
-	struct timespec ts;
+	struct timespec64 ts;
 	struct rtc_time ret;
 
-	ts = ktime_to_timespec(kt);
+	ts = ktime_to_timespec64(kt);
 	/* Round up any ns */
 	if (ts.tv_nsec)
 		ts.tv_sec++;
-	rtc_time_to_tm(ts.tv_sec, &ret);
+	rtc_time64_to_tm(ts.tv_sec, &ret);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(rtc_ktime_to_tm);
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index c2c2897..6d6be09 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -19,11 +19,28 @@
 extern int rtc_month_days(unsigned int month, unsigned int year);
 extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int year);
 extern int rtc_valid_tm(struct rtc_time *tm);
-extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time);
-extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm);
+extern time64_t rtc_tm_to_time64(struct rtc_time *tm);
+extern void rtc_time64_to_tm(time64_t time, struct rtc_time *tm);
 ktime_t rtc_tm_to_ktime(struct rtc_time tm);
 struct rtc_time rtc_ktime_to_tm(ktime_t kt);
 
+/**
+ * Deprecated. Use rtc_time64_to_tm().
+ */
+static inline void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
+{
+	rtc_time64_to_tm(time, tm);
+}
+
+/**
+ * Deprecated. Use rtc_tm_to_time64().
+ */
+static inline int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
+{
+	*time = rtc_tm_to_time64(tm);
+
+	return 0;
+}
 
 #include <linux/device.h>
 #include <linux/seq_file.h>
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC PATCH v3 5/5] rtc/mc13xxx: Eliminate time problems
  2014-11-18 11:15 [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc pang.xunlei
                   ` (3 preceding siblings ...)
  2014-11-18 11:15 ` [RFC PATCH v3 4/5] rtc/lib: Provide y2038 safe rtc_tm_to_time()/rtc_time_to_tm() replacement pang.xunlei
@ 2014-11-18 11:15 ` pang.xunlei
  2014-11-18 14:13 ` [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc Thomas Gleixner
  2014-11-19 23:53 ` John Stultz
  6 siblings, 0 replies; 10+ messages in thread
From: pang.xunlei @ 2014-11-18 11:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: rtc-linux, Thomas Gleixner, Alessandro Zummo, John Stultz,
	Arnd Bergmann, pang.xunlei

This patch is an example to demonstrate how to make rtc drivers
of time-safe hardwares time-safe based on our foregoing work.

Provided mc13xxx_rtc_set_mmss() has been already converted to use
64-bit seconds which will be done in my future patches, now we can
easily tackle all time problems in rtc-mc13xxx.c(time-safe hardware):
- Replace rtc_time_to_tm() with rtc_time64_to_tm()
- Replace rtc_tm_to_time() with rtc_tm_to_time64()

Then, this driver can work properly with no time issues.

Signed-off-by: pang.xunlei <pang.xunlei@linaro.org>
---
 drivers/rtc/rtc-mc13xxx.c |   25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c
index 0765606..124996d 100644
--- a/drivers/rtc/rtc-mc13xxx.c
+++ b/drivers/rtc/rtc-mc13xxx.c
@@ -83,7 +83,7 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
 			return ret;
 	} while (days1 != days2);
 
-	rtc_time_to_tm(days1 * SEC_PER_DAY + seconds, tm);
+	rtc_time64_to_tm((time64_t)days1 * SEC_PER_DAY + seconds, tm);
 
 	return rtc_valid_tm(tm);
 }
@@ -159,7 +159,7 @@ static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 	unsigned seconds, days;
-	unsigned long s1970;
+	time64_t s1970;
 	int enabled, pending;
 	int ret;
 
@@ -189,10 +189,10 @@ out:
 	alarm->enabled = enabled;
 	alarm->pending = pending;
 
-	s1970 = days * SEC_PER_DAY + seconds;
+	s1970 = (time64_t)days * SEC_PER_DAY + seconds;
 
-	rtc_time_to_tm(s1970, &alarm->time);
-	dev_dbg(dev, "%s: %lu\n", __func__, s1970);
+	rtc_time64_to_tm(s1970, &alarm->time);
+	dev_dbg(dev, "%s: %lld\n", __func__, (long long)s1970);
 
 	return 0;
 }
@@ -200,8 +200,8 @@ out:
 static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
-	unsigned long s1970;
-	unsigned seconds, days;
+	time64_t s1970;
+	u32 seconds, days;
 	int ret;
 
 	mc13xxx_lock(priv->mc13xxx);
@@ -215,20 +215,17 @@ static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	if (unlikely(ret))
 		goto out;
 
-	ret = rtc_tm_to_time(&alarm->time, &s1970);
-	if (unlikely(ret))
-		goto out;
+	s1970 = rtc_tm_to_time64(&alarm->time);
 
-	dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff",
-			s1970);
+	dev_dbg(dev, "%s: o%2.s %lld\n", __func__, alarm->enabled ? "n" : "ff",
+			(long long)s1970);
 
 	ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled,
 			MC13XXX_IRQ_TODA);
 	if (unlikely(ret))
 		goto out;
 
-	seconds = s1970 % SEC_PER_DAY;
-	days = s1970 / SEC_PER_DAY;
+	days = div_s64_rem(s1970, SEC_PER_DAY, &seconds);
 
 	ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days);
 	if (unlikely(ret))
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH v3 2/5] time: Provide y2038 safe timekeeping_inject_sleeptime() replacement
  2014-11-18 11:15 ` [RFC PATCH v3 2/5] time: Provide y2038 safe timekeeping_inject_sleeptime() replacement pang.xunlei
@ 2014-11-18 12:05   ` Thomas Gleixner
  0 siblings, 0 replies; 10+ messages in thread
From: Thomas Gleixner @ 2014-11-18 12:05 UTC (permalink / raw)
  To: pang.xunlei
  Cc: linux-kernel, rtc-linux, Alessandro Zummo, John Stultz, Arnd Bergmann

On Tue, 18 Nov 2014, pang.xunlei wrote:

> As part of addressing "y2038 problem" for in-kernel uses, this
> patch adds timekeeping_inject_sleeptime64() using timespec64.
> 
> After this patch, timekeeping_inject_sleeptime() is deprecated
> and all its call sites will be fixed using the new interface,
> after that it can be removed.
> 
> NOTE: timekeeping_inject_sleeptime() is safe actually, but we
> want to eliminate timespec eventually, so comes this patch.

While it's safe, the change gets rid of the timespec conversion, so
it makes sense on its own.
 
> -	tmp = timespec_to_timespec64(*delta);
> -	__timekeeping_inject_sleeptime(tk, &tmp);
> +	__timekeeping_inject_sleeptime(tk, delta);

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc
  2014-11-18 11:15 [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc pang.xunlei
                   ` (4 preceding siblings ...)
  2014-11-18 11:15 ` [RFC PATCH v3 5/5] rtc/mc13xxx: Eliminate time problems pang.xunlei
@ 2014-11-18 14:13 ` Thomas Gleixner
  2014-11-19 13:41   ` pang.xunlei
  2014-11-19 23:53 ` John Stultz
  6 siblings, 1 reply; 10+ messages in thread
From: Thomas Gleixner @ 2014-11-18 14:13 UTC (permalink / raw)
  To: pang.xunlei
  Cc: linux-kernel, rtc-linux, Alessandro Zummo, John Stultz, Arnd Bergmann

On Tue, 18 Nov 2014, pang.xunlei wrote:
> On 32bit systems, the kernel uses a 32bit signed time_t value
> for seconds since 1970-01-01:00:00:00. This will overflow at
> 2038-01-19 03:14:08, and is widely known as the y2038 problem.
> 
> To address this, the plan is to create 64bit internal interfaces
> which are 2038 safe, mark the unsafe versions as deprecated and 
> then convert subsystems one by one over to the new interfaces.
> Once all users are converted, the deprecated internal functions
> will be removed.
> 
> NOTE: In some cases, there are issues with 32bit values that are
> unsigned, and thus become y2106 issues. Since its somewhat simpler
> to unify the time types, we'll try to convert those usage to 64bit
> where it can be easily done. In those cases where a fix would be 
> overly complicated, we'll simply explicitly mark the limitation.
> 
> This patchset introduces the 64bit interfaces needed to convert
> the drivers/rtc subsystem, and to keep it relatively short some
> patches to demonstrate how the conversion will be done. If the 
> feedback is positive on this series, we'll provide the full 
> conversion series as well.

That looks way better than the last attempt.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc
  2014-11-18 14:13 ` [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc Thomas Gleixner
@ 2014-11-19 13:41   ` pang.xunlei
  0 siblings, 0 replies; 10+ messages in thread
From: pang.xunlei @ 2014-11-19 13:41 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: lkml, rtc-linux, Alessandro Zummo, John Stultz, Arnd Bergmann

On 18 November 2014 22:13, Thomas Gleixner <tglx@linutronix.de> wrote:
> On Tue, 18 Nov 2014, pang.xunlei wrote:
>> On 32bit systems, the kernel uses a 32bit signed time_t value
>> for seconds since 1970-01-01:00:00:00. This will overflow at
>> 2038-01-19 03:14:08, and is widely known as the y2038 problem.
>>
>> To address this, the plan is to create 64bit internal interfaces
>> which are 2038 safe, mark the unsafe versions as deprecated and
>> then convert subsystems one by one over to the new interfaces.
>> Once all users are converted, the deprecated internal functions
>> will be removed.
>>
>> NOTE: In some cases, there are issues with 32bit values that are
>> unsigned, and thus become y2106 issues. Since its somewhat simpler
>> to unify the time types, we'll try to convert those usage to 64bit
>> where it can be easily done. In those cases where a fix would be
>> overly complicated, we'll simply explicitly mark the limitation.
>>
>> This patchset introduces the 64bit interfaces needed to convert
>> the drivers/rtc subsystem, and to keep it relatively short some
>> patches to demonstrate how the conversion will be done. If the
>> feedback is positive on this series, we'll provide the full
>> conversion series as well.
>
> That looks way better than the last attempt.
Hi Thomas,

Thanks for your affirmation and former suggestions. I'll send the
another succeeding patchset later.

Regards,
Xunlei
>
> Thanks,
>
>         tglx

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc
  2014-11-18 11:15 [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc pang.xunlei
                   ` (5 preceding siblings ...)
  2014-11-18 14:13 ` [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc Thomas Gleixner
@ 2014-11-19 23:53 ` John Stultz
  6 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2014-11-19 23:53 UTC (permalink / raw)
  To: pang.xunlei
  Cc: lkml, rtc-linux, Thomas Gleixner, Alessandro Zummo, Arnd Bergmann

On Tue, Nov 18, 2014 at 3:15 AM, pang.xunlei <pang.xunlei@linaro.org> wrote:
> On 32bit systems, the kernel uses a 32bit signed time_t value
> for seconds since 1970-01-01:00:00:00. This will overflow at
> 2038-01-19 03:14:08, and is widely known as the y2038 problem.
>
> To address this, the plan is to create 64bit internal interfaces
> which are 2038 safe, mark the unsafe versions as deprecated and
> then convert subsystems one by one over to the new interfaces.
> Once all users are converted, the deprecated internal functions
> will be removed.
>
> NOTE: In some cases, there are issues with 32bit values that are
> unsigned, and thus become y2106 issues. Since its somewhat simpler
> to unify the time types, we'll try to convert those usage to 64bit
> where it can be easily done. In those cases where a fix would be
> overly complicated, we'll simply explicitly mark the limitation.
>
> This patchset introduces the 64bit interfaces needed to convert
> the drivers/rtc subsystem, and to keep it relatively short some
> patches to demonstrate how the conversion will be done. If the
> feedback is positive on this series, we'll provide the full
> conversion series as well.
>
> pang.xunlei (5):
>   time: Provide y2038 safe do_settimeofday() replacement
>   time: Provide y2038 safe timekeeping_inject_sleeptime() replacement
>   time: Provide y2038 safe mktime() replacement
>   rtc/lib: Provide y2038 safe rtc_tm_to_time()/rtc_time_to_tm()
>     replacement
>   rtc/mc13xxx: Eliminate time problems

Ok, I've queued these up for testing in my tree. Hope to send them off
to Thomas for 3.19.

thanks
-john

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-11-19 23:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-18 11:15 [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc pang.xunlei
2014-11-18 11:15 ` [RFC PATCH v3 1/5] time: Provide y2038 safe do_settimeofday() replacement pang.xunlei
2014-11-18 11:15 ` [RFC PATCH v3 2/5] time: Provide y2038 safe timekeeping_inject_sleeptime() replacement pang.xunlei
2014-11-18 12:05   ` Thomas Gleixner
2014-11-18 11:15 ` [RFC PATCH v3 3/5] time: Provide y2038 safe mktime() replacement pang.xunlei
2014-11-18 11:15 ` [RFC PATCH v3 4/5] rtc/lib: Provide y2038 safe rtc_tm_to_time()/rtc_time_to_tm() replacement pang.xunlei
2014-11-18 11:15 ` [RFC PATCH v3 5/5] rtc/mc13xxx: Eliminate time problems pang.xunlei
2014-11-18 14:13 ` [RFC PATCH v3 0/5] y2038 in-kernel interface changes for drivers/rtc Thomas Gleixner
2014-11-19 13:41   ` pang.xunlei
2014-11-19 23:53 ` John Stultz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).