]> git.proxmox.com Git - mirror_qemu.git/commit - hw/intc/riscv_aclint.c
hw/intc/sifive_clint: Fix muldiv64 overflow in sifive_clint_write_timecmp()
authorDavid Hoppenbrouwers <david@salt-inc.org>
Fri, 27 Aug 2021 15:23:25 +0000 (17:23 +0200)
committerAlistair Francis <alistair.francis@wdc.com>
Wed, 1 Sep 2021 01:59:12 +0000 (11:59 +1000)
commit4dc06bb8167fb18b8eb7e40762a94dcc36101047
tree77bcca69ad88f3771f7b9886fcc4e2e7a6533cc3
parent33fcedfac8af376afad478f029cebb9ddb09f74a
hw/intc/sifive_clint: Fix muldiv64 overflow in sifive_clint_write_timecmp()

`muldiv64` would overflow in cases where the final 96-bit value does not
fit in a `uint64_t`. This would result in small values that cause an
interrupt to be triggered much sooner than intended.

The overflow can be detected in most cases by checking if the new value is
smaller than the previous value. If the final result is larger than
`diff` it is either correct or it doesn't matter as it is effectively
infinite anyways.

`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 <david@salt-inc.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20210827152324.5201-1-david@salt-inc.org
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
hw/intc/sifive_clint.c