lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <10bb949d-07f5-5cea-b658-8969b5bda6ae@linux-m68k.org>
Date: Sat, 5 Oct 2024 14:23:28 +1000 (AEST)
From: Finn Thain <fthain@...ux-m68k.org>
To: Alexandre Belloni <alexandre.belloni@...tlin.com>
cc: Geert Uytterhoeven <geert@...ux-m68k.org>, Daniel Palmer <daniel@...f.com>, 
    Michael Pavone <pavone@...rodev.com>, linux-m68k@...ts.linux-m68k.org, 
    linux-rtc@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 1/2] rtc: m48t59: Accommodate chips that lack a century
 bit


On Thu, 3 Oct 2024, Alexandre Belloni wrote:

> 
> ... while you are it, can you use m48t59->rtc->start_secs and 
> m48t59->rtc->set_start_time in probe instead of offsetting tm_year in 
> read_time/set_time so we can later use device tree or any other 
> mechanism to extend the range?
> 

That didn't work out as I'd hoped. I booted a patched kernel (diff below) 
under qemu-system-sparc64:

~ # for yyyy in 1970 1971 1999 2000 2024 2025 2068 2069 ; do 
date 01010101$yyyy ; hwclock --systohc --utc && hwclock --utc ; echo ; done
Thu Jan  1 01:01:00 UTC 1970
Thu Jan  1 01:01:00 1970  0.000000 seconds

Fri Jan  1 01:01:00 UTC 1971
Tue Nov 24 18:32:44 1998  0.000000 seconds

Fri Jan  1 01:01:00 UTC 1999
Tue Nov 24 18:32:44 2026  0.000000 seconds

Sat Jan  1 01:01:00 UTC 2000
Sun Jan  2 23:29:16 2000  0.000000 seconds

Mon Jan  1 01:01:00 UTC 2024
Tue Jan  2 23:29:16 2024  0.000000 seconds

Wed Jan  1 01:01:00 UTC 2025
Thu Jan  2 23:29:16 2025  0.000000 seconds

Sun Jan  1 01:01:00 UTC 2068
hwclock: RTC_SET_TIME: Numerical result out of range

Tue Jan  1 01:01:00 UTC 2069
hwclock: RTC_SET_TIME: Numerical result out of range

~ # 

Here's the result from an unpatched kernel (v6.11):

~ # for yyyy in 1970 1971 1999 2000 2024 2025 2068 2069 ; do 
date 01010101$yyyy ; hwclock --systohc --utc && hwclock --utc ; echo ; done
Thu Jan  1 01:01:00 UTC 1970
Thu Jan  1 01:01:00 1970  0.000000 seconds

Fri Jan  1 01:01:00 UTC 1971
Fri Jan  1 01:01:00 1971  0.000000 seconds

Fri Jan  1 01:01:00 UTC 1999
Fri Jan  1 01:01:01 1999  0.000000 seconds

Sat Jan  1 01:01:00 UTC 2000
Sat Jan  1 01:01:00 2000  0.000000 seconds

Mon Jan  1 01:01:00 UTC 2024
Mon Jan  1 01:01:00 2024  0.000000 seconds

Wed Jan  1 01:01:00 UTC 2025
Wed Jan  1 01:01:00 2025  0.000000 seconds

Sun Jan  1 01:01:00 UTC 2068
hwclock: RTC_RD_TIME: Invalid argument

Tue Jan  1 01:01:00 UTC 2069
hwclock: RTC_RD_TIME: Invalid argument

~ # 


I'm afraid I don't see how we might avoid adding/subtracting in 
read_time/set_time given that we must avoid messing up the present date 
when users boot into an upgraded kernel.


diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 08bbdc458596..41ae3d1aa12e 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -255,6 +255,7 @@ static void mostek_write_byte(struct device *dev, u32 ofs, u8 val)
 static struct m48t59_plat_data m48t59_data = {
 	.read_byte = mostek_read_byte,
 	.write_byte = mostek_write_byte,
+	.start_year = 1968,
 };
 
 /* resource is set at runtime */
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 60f1c8cc5363..eceb3fadb71a 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -544,6 +544,7 @@ static void mostek_write_byte(struct device *dev, u32 ofs, u8 val)
 static struct m48t59_plat_data m48t59_data = {
 	.read_byte	= mostek_read_byte,
 	.write_byte	= mostek_write_byte,
+	.start_year	= 1968,
 };
 
 static struct platform_device m48t59_rtc = {
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index f0f6b9b6daec..d7e1f79cd52b 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -82,10 +82,6 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
 		dev_dbg(dev, "Century bit is enabled\n");
 		tm->tm_year += 100;	/* one century */
 	}
-#ifdef CONFIG_SPARC
-	/* Sun SPARC machines count years since 1968 */
-	tm->tm_year += 68;
-#endif
 
 	tm->tm_wday	= bcd2bin(val & 0x07);
 	tm->tm_hour	= bcd2bin(M48T59_READ(M48T59_HOUR) & 0x3F);
@@ -108,11 +104,6 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	u8 val = 0;
 	int year = tm->tm_year;
 
-#ifdef CONFIG_SPARC
-	/* Sun SPARC machines count years since 1968 */
-	year -= 68;
-#endif
-
 	dev_dbg(dev, "RTC set time %04d-%02d-%02d %02d/%02d/%02d\n",
 		year + 1900, tm->tm_mon, tm->tm_mday,
 		tm->tm_hour, tm->tm_min, tm->tm_sec);
@@ -163,10 +154,7 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL);
 
 	tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR));
-#ifdef CONFIG_SPARC
-	/* Sun SPARC machines count years since 1968 */
-	tm->tm_year += 68;
-#endif
+
 	/* tm_mon is 0-11 */
 	tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1;
 
@@ -199,11 +187,6 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	unsigned long flags;
 	int year = tm->tm_year;
 
-#ifdef CONFIG_SPARC
-	/* Sun SPARC machines count years since 1968 */
-	year -= 68;
-#endif
-
 	/* If no irq, we don't support ALARM */
 	if (m48t59->irq == NO_IRQ)
 		return -EIO;
@@ -458,6 +441,10 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, m48t59);
 
 	m48t59->rtc->ops = &m48t59_rtc_ops;
+	m48t59->rtc->range_min = mktime64(1900, 1, 1, 0, 0, 0);
+	m48t59->rtc->range_max = mktime64(1999, 12, 31, 23, 59, 59);
+	m48t59->rtc->start_secs = mktime64(pdata->start_year, 1, 1, 0, 0, 0);
+	m48t59->rtc->set_start_time = true;
 
 	nvmem_cfg.size = pdata->offset;
 	ret = devm_rtc_nvmem_register(m48t59->rtc, &nvmem_cfg);
diff --git a/include/linux/rtc/m48t59.h b/include/linux/rtc/m48t59.h
index 9465d5405fe2..b01c514d7079 100644
--- a/include/linux/rtc/m48t59.h
+++ b/include/linux/rtc/m48t59.h
@@ -56,6 +56,9 @@ struct m48t59_plat_data {
 	void __iomem *ioaddr;
 	/* offset to RTC registers, automatically set according to the type */
 	unsigned int offset;
+
+	/* value to be used to initialize rtc->start_secs */
+	time64_t start_year;
 };
 
 #endif /* _LINUX_RTC_M48T59_H_ */

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ