`next` is an `uint64_t` value, but `timer_mod` takes an `int64_t`. This resulted in high values such as `UINT64_MAX` being converted to `-1`, which caused an immediate timer interrupt.
By limiting `next` to `INT64_MAX` no overflow will happen while the timer will still be effectively set to "infinitely" far in the future. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/493 Signed-off-by: David Hoppenbrouwers <da...@salt-inc.org> --- I wrongly used `MAX` instead of `MIN`. I've amended the patch. hw/intc/sifive_clint.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c index 0f41e5ea1c..de47571fca 100644 --- a/hw/intc/sifive_clint.c +++ b/hw/intc/sifive_clint.c @@ -61,6 +61,8 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value, /* back to ns (note args switched in muldiv64) */ next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); + /* ensure next does not overflow, as timer_mod takes a signed value */ + next = MIN(next, INT64_MAX); timer_mod(cpu->env.timer, next); } -- 2.20.1