Skip to content

Commit eb92f0f

Browse files
maxikriejerpelea
authored andcommitted
drivers/timers: avoid 32-bit overflow in arch_timer current_usec
current_usec() returns a uint64_t, but it used TICK2USEC(timebase) to convert scheduler ticks to microseconds. On 32-bit clock_t builds, TICK2USEC() performs the multiplication in 32-bit arithmetic before the result is widened. With CONFIG_USEC_PER_TICK=10000, this wraps after about 71.6 minutes: UINT32_MAX / 1000000 ~= 4294 seconds After the wrap, up_timer_gettick() can report time near zero again. This can leave absolute watchdog timeouts, such as those used by usleep() / clock_nanosleep(), waiting for a tick value that will not be reached until the 32-bit scheduler counter wraps. Cast timebase to uint64_t before multiplying by USEC_PER_TICK so current_usec() remains monotonic across the 32-bit microsecond boundary. Signed-off-by: Max Kriegleder <max.kriegleder@gmail.com>
1 parent 990ac85 commit eb92f0f

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

drivers/timers/arch_timer.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ static uint64_t current_usec(void)
114114
}
115115
while (timebase != g_timer.timebase);
116116

117-
return TICK2USEC(timebase) + (status.timeout - status.timeleft);
117+
return TICK2USEC((uint64_t)timebase) +
118+
(status.timeout - status.timeleft);
118119
}
119120

120121
static void udelay_accurate(useconds_t microseconds)

0 commit comments

Comments
 (0)