LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 1/3] rtc: vr41xx: remove mktime usage
@ 2018-04-20 16:14 Arnd Bergmann
  2018-04-20 16:14 ` [PATCH 2/3] rtc: ls1x: " Arnd Bergmann
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Arnd Bergmann @ 2018-04-20 16:14 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni
  Cc: y2038, Arnd Bergmann, linux-rtc, linux-kernel

This driver uses mktime() and rtc_time_to_tm() to convert between time
values. This works fine on 64-bit kernels over the whole supported
range, and the vr41xx chip is a 64-bit MIPS implementation, but it is
inconsistent because it doesn't do the same thing on 32-bit kernels that
overflow in 2106 or 2038.

Changing it to use mktime64/rtc_time64_to_tm() should have no visible
impact on vr41xx but gets us closer to removing the 32-bit interfaces.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/rtc/rtc-vr41xx.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index 7ce22967fd16..480cffe8d321 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -88,7 +88,7 @@ static unsigned int alarm_enabled;
 static int aie_irq;
 static int pie_irq;
 
-static inline unsigned long read_elapsed_second(void)
+static inline time64_t read_elapsed_second(void)
 {
 
 	unsigned long first_low, first_mid, first_high;
@@ -105,10 +105,10 @@ static inline unsigned long read_elapsed_second(void)
 	} while (first_low != second_low || first_mid != second_mid ||
 		 first_high != second_high);
 
-	return (first_high << 17) | (first_mid << 1) | (first_low >> 15);
+	return ((u64)first_high << 17) | (first_mid << 1) | (first_low >> 15);
 }
 
-static inline void write_elapsed_second(unsigned long sec)
+static inline void write_elapsed_second(time64_t sec)
 {
 	spin_lock_irq(&rtc_lock);
 
@@ -121,22 +121,22 @@ static inline void write_elapsed_second(unsigned long sec)
 
 static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time)
 {
-	unsigned long epoch_sec, elapsed_sec;
+	time64_t epoch_sec, elapsed_sec;
 
-	epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
+	epoch_sec = mktime64(epoch, 1, 1, 0, 0, 0);
 	elapsed_sec = read_elapsed_second();
 
-	rtc_time_to_tm(epoch_sec + elapsed_sec, time);
+	rtc_time64_to_tm(epoch_sec + elapsed_sec, time);
 
 	return 0;
 }
 
 static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time)
 {
-	unsigned long epoch_sec, current_sec;
+	time64_t epoch_sec, current_sec;
 
-	epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
-	current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
+	epoch_sec = mktime64(epoch, 1, 1, 0, 0, 0);
+	current_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
 			     time->tm_hour, time->tm_min, time->tm_sec);
 
 	write_elapsed_second(current_sec - epoch_sec);
@@ -165,11 +165,11 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 
 static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 {
-	unsigned long alarm_sec;
+	time64_t alarm_sec;
 	struct rtc_time *time = &wkalrm->time;
 
-	alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
-			   time->tm_hour, time->tm_min, time->tm_sec);
+	alarm_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
+			     time->tm_hour, time->tm_min, time->tm_sec);
 
 	spin_lock_irq(&rtc_lock);
 
-- 
2.9.0

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

* [PATCH 2/3] rtc: ls1x: remove mktime usage
  2018-04-20 16:14 [PATCH 1/3] rtc: vr41xx: remove mktime usage Arnd Bergmann
@ 2018-04-20 16:14 ` Arnd Bergmann
  2018-04-20 16:14 ` [PATCH 3/3] rtc: tps6586x: " Arnd Bergmann
  2018-05-16 13:55 ` [PATCH 1/3] rtc: vr41xx: " Alexandre Belloni
  2 siblings, 0 replies; 5+ messages in thread
From: Arnd Bergmann @ 2018-04-20 16:14 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni
  Cc: y2038, Arnd Bergmann, linux-rtc, linux-kernel

The loongson1 platform is 32-bit, so storing a time value in 32 bits
suffers from limited range. In this case it is likely to be correct
until 2106, but it's better to avoid the limitation and just use
the time64_t based mktime64() and rtc_time64_to_tm() interfaces.

The hardware uses a 32-bit year number, and time64_t can cover that
entire range.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/rtc/rtc-ls1x.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c
index 045af1135e48..de86f9fabc11 100644
--- a/drivers/rtc/rtc-ls1x.c
+++ b/drivers/rtc/rtc-ls1x.c
@@ -87,16 +87,17 @@
 
 static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm)
 {
-	unsigned long v, t;
+	unsigned long v;
+	time64_t t;
 
 	v = readl(SYS_TOYREAD0);
 	t = readl(SYS_TOYREAD1);
 
 	memset(rtm, 0, sizeof(struct rtc_time));
-	t  = mktime((t & LS1X_YEAR_MASK), ls1x_get_month(v),
+	t  = mktime64((t & LS1X_YEAR_MASK), ls1x_get_month(v),
 			ls1x_get_day(v), ls1x_get_hour(v),
 			ls1x_get_min(v), ls1x_get_sec(v));
-	rtc_time_to_tm(t, rtm);
+	rtc_time64_to_tm(t, rtm);
 
 	return 0;
 }
-- 
2.9.0

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

* [PATCH 3/3] rtc: tps6586x: remove mktime usage
  2018-04-20 16:14 [PATCH 1/3] rtc: vr41xx: remove mktime usage Arnd Bergmann
  2018-04-20 16:14 ` [PATCH 2/3] rtc: ls1x: " Arnd Bergmann
@ 2018-04-20 16:14 ` Arnd Bergmann
  2018-05-16 13:55 ` [PATCH 1/3] rtc: vr41xx: " Alexandre Belloni
  2 siblings, 0 replies; 5+ messages in thread
From: Arnd Bergmann @ 2018-04-20 16:14 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni
  Cc: y2038, Arnd Bergmann, linux-rtc, linux-kernel

The tps6586x use a 64-bit 'epoch_start' value, but then computes that
value using an 'mktime()', which has a smaller range and overflows
in 2106 at the latest. As both the hardware and the subsystem interface
support wider than 32-bit ranges for rtc times here, let's change all
the operations on 'seconds' to time64_t.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/rtc/rtc-tps6586x.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c
index d7785ae0a2b4..46a19adf9a96 100644
--- a/drivers/rtc/rtc-tps6586x.c
+++ b/drivers/rtc/rtc-tps6586x.c
@@ -58,7 +58,7 @@ struct tps6586x_rtc {
 	struct rtc_device	*rtc;
 	int			irq;
 	bool			irq_en;
-	unsigned long long	epoch_start;
+	time64_t		epoch_start;
 };
 
 static inline struct device *to_tps6586x_dev(struct device *dev)
@@ -71,7 +71,7 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
 	struct device *tps_dev = to_tps6586x_dev(dev);
 	unsigned long long ticks = 0;
-	unsigned long seconds;
+	time64_t seconds;
 	u8 buff[6];
 	int ret;
 	int i;
@@ -98,11 +98,11 @@ static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
 	struct device *tps_dev = to_tps6586x_dev(dev);
 	unsigned long long ticks;
-	unsigned long seconds;
+	time64_t seconds;
 	u8 buff[5];
 	int ret;
 
-	rtc_tm_to_time(tm, &seconds);
+	seconds = rtc_tm_to_time64(tm);
 	if (seconds < rtc->epoch_start) {
 		dev_err(dev, "requested time unsupported\n");
 		return -EINVAL;
@@ -157,7 +157,7 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
 	struct device *tps_dev = to_tps6586x_dev(dev);
-	unsigned long seconds;
+	time64_t seconds;
 	unsigned long ticks;
 	unsigned long rtc_current_time;
 	unsigned long long rticks = 0;
@@ -166,7 +166,7 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	int ret;
 	int i;
 
-	rtc_tm_to_time(&alrm->time, &seconds);
+	seconds = rtc_tm_to_time64(&alrm->time);
 
 	if (alrm->enabled && (seconds < rtc->epoch_start)) {
 		dev_err(dev, "can't set alarm to requested time\n");
@@ -213,7 +213,7 @@ static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
 	struct device *tps_dev = to_tps6586x_dev(dev);
 	unsigned long ticks;
-	unsigned long seconds;
+	time64_t seconds;
 	u8 buff[3];
 	int ret;
 
@@ -227,7 +227,7 @@ static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	seconds = ticks >> 10;
 	seconds += rtc->epoch_start;
 
-	rtc_time_to_tm(seconds, &alrm->time);
+	rtc_time64_to_tm(seconds, &alrm->time);
 	return 0;
 }
 
@@ -261,7 +261,7 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
 	rtc->irq = platform_get_irq(pdev, 0);
 
 	/* Set epoch start as 00:00:00:01:01:2009 */
-	rtc->epoch_start = mktime(2009, 1, 1, 0, 0, 0);
+	rtc->epoch_start = mktime64(2009, 1, 1, 0, 0, 0);
 
 	/* 1 kHz tick mode, enable tick counting */
 	ret = tps6586x_update(tps_dev, RTC_CTRL,
-- 
2.9.0

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

* Re: [PATCH 1/3] rtc: vr41xx: remove mktime usage
  2018-04-20 16:14 [PATCH 1/3] rtc: vr41xx: remove mktime usage Arnd Bergmann
  2018-04-20 16:14 ` [PATCH 2/3] rtc: ls1x: " Arnd Bergmann
  2018-04-20 16:14 ` [PATCH 3/3] rtc: tps6586x: " Arnd Bergmann
@ 2018-05-16 13:55 ` Alexandre Belloni
  2018-05-17  3:43   ` Arnd Bergmann
  2 siblings, 1 reply; 5+ messages in thread
From: Alexandre Belloni @ 2018-05-16 13:55 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Alessandro Zummo, y2038, linux-rtc, linux-kernel

Hi,

On 20/04/2018 18:14:24+0200, Arnd Bergmann wrote:
> This driver uses mktime() and rtc_time_to_tm() to convert between time
> values. This works fine on 64-bit kernels over the whole supported
> range, and the vr41xx chip is a 64-bit MIPS implementation, but it is
> inconsistent because it doesn't do the same thing on 32-bit kernels that
> overflow in 2106 or 2038.
> 
> Changing it to use mktime64/rtc_time64_to_tm() should have no visible
> impact on vr41xx but gets us closer to removing the 32-bit interfaces.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  drivers/rtc/rtc-vr41xx.c | 24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
> 

I've applied the series a while ago. It should be noted that mktime64
will fail on 32bit platforms in year 21000 or so but I pretty sure it is
not worth fixing. My understanding is that the kernel will fail in April
2262 anyway as ktime_t will overflow.

Note that I will be following up with multiple series adding proper
rtc HW range, removing set_mmss and rtc_time_to_tm/rtc_tm_to_time64.

-- 
Alexandre Belloni, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH 1/3] rtc: vr41xx: remove mktime usage
  2018-05-16 13:55 ` [PATCH 1/3] rtc: vr41xx: " Alexandre Belloni
@ 2018-05-17  3:43   ` Arnd Bergmann
  0 siblings, 0 replies; 5+ messages in thread
From: Arnd Bergmann @ 2018-05-17  3:43 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Alessandro Zummo, y2038 Mailman List, linux-rtc,
	Linux Kernel Mailing List

On Wed, May 16, 2018 at 9:55 AM, Alexandre Belloni
<alexandre.belloni@bootlin.com> wrote:
> Hi,
>
> On 20/04/2018 18:14:24+0200, Arnd Bergmann wrote:
>> This driver uses mktime() and rtc_time_to_tm() to convert between time
>> values. This works fine on 64-bit kernels over the whole supported
>> range, and the vr41xx chip is a 64-bit MIPS implementation, but it is
>> inconsistent because it doesn't do the same thing on 32-bit kernels that
>> overflow in 2106 or 2038.
>>
>> Changing it to use mktime64/rtc_time64_to_tm() should have no visible
>> impact on vr41xx but gets us closer to removing the 32-bit interfaces.
>>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> ---
>>  drivers/rtc/rtc-vr41xx.c | 24 ++++++++++++------------
>>  1 file changed, 12 insertions(+), 12 deletions(-)
>>
>
> I've applied the series a while ago.

Thanks! We should be able to remove mktime() in the near future then,
along with some other interfaces from linux/time32.h and linux/timekeeping32.h.

> It should be noted that mktime64
> will fail on 32bit platforms in year 21000 or so but I pretty sure it is
> not worth fixing. My understanding is that the kernel will fail in April
> 2262 anyway as ktime_t will overflow.

Right.

> Note that I will be following up with multiple series adding proper
> rtc HW range, removing set_mmss and rtc_time_to_tm/rtc_tm_to_time64.

Ok, looking forward to those patches!

        Arnd

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

end of thread, other threads:[~2018-05-17  3:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-20 16:14 [PATCH 1/3] rtc: vr41xx: remove mktime usage Arnd Bergmann
2018-04-20 16:14 ` [PATCH 2/3] rtc: ls1x: " Arnd Bergmann
2018-04-20 16:14 ` [PATCH 3/3] rtc: tps6586x: " Arnd Bergmann
2018-05-16 13:55 ` [PATCH 1/3] rtc: vr41xx: " Alexandre Belloni
2018-05-17  3:43   ` Arnd Bergmann

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).