Hello,
as described in the commit log of the two commits the rtc-mt6397 driver relies on these fixes as soon as it should store dates later than 2027-12-31. On one of the patches has a Fixes line, so this submission is done to ensure that both patches are backported.
The patches sent in reply to this mail are (trivial) backports to v6.15.1, they should get backported to the older stable kernels, too, to (somewhat) ensure that in 2028 no surprises happen. `git am` is able to apply the patches as is to 6.14.y, 6.12.y, 6.6.y, 6.1.y and 5.15.y.
5.10 and 5.4 need an adaption, I didn't look into that yet but can follow up with backports for these.
The two fixes were accompanied by 3 test updates:
46351921cbe1 ("rtc: test: Emit the seconds-since-1970 value instead of days-since-1970") da62b49830f8 ("rtc: test: Also test time and wday outcome of rtc_time64_to_tm()") ccb2dba3c19f ("rtc: test: Test date conversion for dates starting in 1900")
that cover one of the patches. Would you consider it sensible to backport these, too?
Best regards Uwe
Alexandre Mergnat (2): rtc: Make rtc_time64_to_tm() support dates before 1970 rtc: Fix offset calculation for .start_secs < 0
drivers/rtc/class.c | 2 +- drivers/rtc/lib.c | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-)
base-commit: 3ef49626da6dd67013fc2cf0a4e4c9e158bb59f7
From: Alexandre Mergnat amergnat@baylibre.com
commit 7df4cfef8b351fec3156160bedfc7d6d29de4cce upstream.
Conversion of dates before 1970 is still relevant today because these dates are reused on some hardwares to store dates bigger than the maximal date that is representable in the device's native format. This prominently and very soon affects the hardware covered by the rtc-mt6397 driver that can only natively store dates in the interval 1900-01-01 up to 2027-12-31. So to store the date 2028-01-01 00:00:00 to such a device, rtc_time64_to_tm() must do the right thing for time=-2208988800.
Signed-off-by: Alexandre Mergnat amergnat@baylibre.com Reviewed-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-1-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com --- drivers/rtc/lib.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/rtc/lib.c b/drivers/rtc/lib.c index fe361652727a..13b5b1f20465 100644 --- a/drivers/rtc/lib.c +++ b/drivers/rtc/lib.c @@ -46,24 +46,38 @@ EXPORT_SYMBOL(rtc_year_days); * rtc_time64_to_tm - converts time64_t to rtc_time. * * @time: The number of seconds since 01-01-1970 00:00:00. - * (Must be positive.) + * Works for values since at least 1900 * @tm: Pointer to the struct rtc_time. */ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) { - unsigned int secs; - int days; + int days, secs;
u64 u64tmp; u32 u32tmp, udays, century, day_of_century, year_of_century, year, day_of_year, month, day; bool is_Jan_or_Feb, is_leap_year;
- /* time must be positive */ + /* + * Get days and seconds while preserving the sign to + * handle negative time values (dates before 1970-01-01) + */ days = div_s64_rem(time, 86400, &secs);
+ /* + * We need 0 <= secs < 86400 which isn't given for negative + * values of time. Fixup accordingly. + */ + if (secs < 0) { + days -= 1; + secs += 86400; + } + /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; + /* Ensure tm_wday is always positive */ + if (tm->tm_wday < 0) + tm->tm_wday += 7;
/* * The following algorithm is, basically, Proposition 6.3 of Neri @@ -93,7 +107,7 @@ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) * thus, is slightly different from [1]. */
- udays = ((u32) days) + 719468; + udays = days + 719468;
u32tmp = 4 * udays + 3; century = u32tmp / 146097;
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 7df4cfef8b351fec3156160bedfc7d6d29de4cce
WARNING: Author mismatch between patch and upstream commit: Backport author: u.kleine-koenig@baylibre.com Commit author: Alexandre Mergnatamergnat@baylibre.com
Note: The patch differs from the upstream commit: --- 1: 7df4cfef8b351 ! 1: 6da0666c8846e rtc: Make rtc_time64_to_tm() support dates before 1970 @@ Metadata ## Commit message ## rtc: Make rtc_time64_to_tm() support dates before 1970
+ commit 7df4cfef8b351fec3156160bedfc7d6d29de4cce upstream. + Conversion of dates before 1970 is still relevant today because these dates are reused on some hardwares to store dates bigger than the maximal date that is representable in the device's native format. @@ Commit message Reviewed-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-1-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com + Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com
## drivers/rtc/lib.c ## @@ drivers/rtc/lib.c: EXPORT_SYMBOL(rtc_year_days); ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.15.y | Success | Success |
From: Alexandre Mergnat amergnat@baylibre.com
commit fe9f5f96cfe8b82d0f24cbfa93718925560f4f8d upstream.
The comparison
rtc->start_secs > rtc->range_max
has a signed left-hand side and an unsigned right-hand side. So the comparison might become true for negative start_secs which is interpreted as a (possibly very large) positive value.
As a negative value can never be bigger than an unsigned value the correct representation of the (mathematical) comparison
rtc->start_secs > rtc->range_max
in C is:
rtc->start_secs >= 0 && rtc->start_secs > rtc->range_max
Use that to fix the offset calculation currently used in the rtc-mt6397 driver.
Fixes: 989515647e783 ("rtc: Add one offset seconds to expand RTC range") Signed-off-by: Alexandre Mergnat amergnat@baylibre.com Reviewed-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-2-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com --- drivers/rtc/class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index b88cd4fb295b..b1a2be1f9e3b 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -326,7 +326,7 @@ static void rtc_device_get_offset(struct rtc_device *rtc) * * Otherwise the offset seconds should be 0. */ - if (rtc->start_secs > rtc->range_max || + if ((rtc->start_secs >= 0 && rtc->start_secs > rtc->range_max) || rtc->start_secs + range_secs - 1 < rtc->range_min) rtc->offset_secs = rtc->start_secs - rtc->range_min; else if (rtc->start_secs > rtc->range_min)
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: fe9f5f96cfe8b82d0f24cbfa93718925560f4f8d
WARNING: Author mismatch between patch and upstream commit: Backport author: u.kleine-koenig@baylibre.com Commit author: Alexandre Mergnatamergnat@baylibre.com
Note: The patch differs from the upstream commit: --- 1: fe9f5f96cfe8b ! 1: 6c5107e2d5c38 rtc: Fix offset calculation for .start_secs < 0 @@ Metadata ## Commit message ## rtc: Fix offset calculation for .start_secs < 0
+ commit fe9f5f96cfe8b82d0f24cbfa93718925560f4f8d upstream. + The comparison
rtc->start_secs > rtc->range_max @@ Commit message Reviewed-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-2-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com + Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com
## drivers/rtc/class.c ## @@ drivers/rtc/class.c: static void rtc_device_get_offset(struct rtc_device *rtc) ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.4.y | Success | Success |
On Fri, Jun 06, 2025 at 05:44:37PM +0200, Uwe Kleine-König wrote:
Hello,
as described in the commit log of the two commits the rtc-mt6397 driver relies on these fixes as soon as it should store dates later than 2027-12-31. On one of the patches has a Fixes line, so this submission is done to ensure that both patches are backported.
The patches sent in reply to this mail are (trivial) backports to v6.15.1, they should get backported to the older stable kernels, too, to (somewhat) ensure that in 2028 no surprises happen. `git am` is able to apply the patches as is to 6.14.y, 6.12.y, 6.6.y, 6.1.y and 5.15.y.
5.10 and 5.4 need an adaption, I didn't look into that yet but can follow up with backports for these.
The two fixes were accompanied by 3 test updates:
46351921cbe1 ("rtc: test: Emit the seconds-since-1970 value instead of days-since-1970") da62b49830f8 ("rtc: test: Also test time and wday outcome of rtc_time64_to_tm()") ccb2dba3c19f ("rtc: test: Test date conversion for dates starting in 1900")
that cover one of the patches. Would you consider it sensible to backport these, too?
If you want to, sure, but normally people run the latest in-kernel selftests for older kernel trees.
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org