* [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
* 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
* [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 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