Re: [PATCH] rtc: ftrtc010: fix negative offset handling and smatch warning

From: Alexandre Belloni

Date: Thu Oct 08 2026 - 07:59:31 EST


On 08/10/2026 19:37:32+0800, Liu Dalin wrote:
> A prior attempted to fix the 32-bit arithmetic overflow by turning
> the implicit u32-to-timeu64_t cast into an explicit one. However,
> all calculations still happen in u32, inheriting the existing
> negative offset sign-extension bug, and the explicit cast triggers
> smatch "cast after binop" warning.
>

AI is lying to you, offset will never ever be negative.

> The FTRTC010 RECORD register stores a signed 32-bit two's complement
> offset exposed through readl() as a u32. Casting the whole u32
> expression result to timeu64_t performs zero extension, so negative
> offsets become huge positive values.
>
> Fix it by casting offset to s32 first to correctly interpret the
> two's complement sign, then promote all operands to timeu64_t so all
> calculations are done in 64-bit space. days/hour/min/sec are
> non-negative hardware counters, so promoting them directly to
> timeu64_t is safe.
>
> Fixes: 1d61d2592c1f ("rtc: gemini/ftrtc010: rename driver and symbols")
>
> Signed-off-by: Liu Dalin <liudalin@xxxxxxxxxxxxxxx>
> ---
> drivers/rtc/rtc-ftrtc010.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c
> index b29c96be40f4..65fe1e872239 100644
> --- a/drivers/rtc/rtc-ftrtc010.c
> +++ b/drivers/rtc/rtc-ftrtc010.c
> @@ -72,7 +72,8 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
> days = readl(rtc->rtc_base + FTRTC010_RTC_DAYS);
> offset = readl(rtc->rtc_base + FTRTC010_RTC_RECORD);
>
> - time = (timeu64_t)(offset + days * 86400 + hour * 3600 + min * 60 + sec);
> + time = (timeu64_t)(s32)offset + (timeu64_t)days * 86400 +
> + (timeu64_t)hour * 3600 + (timeu64_t)min * 60 + (timeu64_t)sec;
>
> rtc_time64_to_tm(time, tm);
>
> --
> 2.43.0
>

--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com