risc-v: 0.995 architecture: 0.955 graphic: 0.849 device: 0.810 performance: 0.696 semantic: 0.644 files: 0.588 kernel: 0.547 register: 0.533 vnc: 0.466 socket: 0.369 mistranslation: 0.368 network: 0.353 debug: 0.295 boot: 0.272 VMM: 0.271 arm: 0.242 permissions: 0.230 peripherals: 0.215 PID: 0.206 ppc: 0.193 TCG: 0.157 user-level: 0.146 assembly: 0.130 hypervisor: 0.121 virtual: 0.099 i386: 0.079 KVM: 0.064 x86: 0.016 -------------------- risc-v: 0.998 performance: 0.905 kernel: 0.184 register: 0.116 TCG: 0.113 debug: 0.104 files: 0.080 hypervisor: 0.038 assembly: 0.032 architecture: 0.029 device: 0.021 virtual: 0.015 semantic: 0.008 peripherals: 0.007 user-level: 0.005 vnc: 0.003 PID: 0.003 network: 0.002 KVM: 0.002 boot: 0.002 VMM: 0.002 arm: 0.001 socket: 0.001 graphic: 0.001 permissions: 0.001 mistranslation: 0.000 i386: 0.000 ppc: 0.000 x86: 0.000 RISC-V: Setting mtimecmp to -1 immediately triggers an interrupt Description of problem: When setting mtimecmp to -1, which should set a timer infinitely far in the future, a timer interrupt is triggered immediately. This happens for most values over 2^61. It is the same for both 32-bit and 64-bit, and for M-mode writing to mtimecmp directly and S-mode using OpenSBI. I have looked through the source code, and the problem is in the function `sifive_clint_write_mtimecmp`, in the file `/hw/intc/sifive_clint.c`. First, the muldiv64 multiplies diff with 100, causing an overflow (at least for -M virt, other machines might use a different timebase_freq). Then, the unsigned `next` is passed to `timer_mod`, which takes a signed integer. In `timer_mod_ns_locked` the value is set to `MAX(next, 0)`, which means that if the MSB of `next` was set, the interrupt happens immediately. This means that it is impossible to set timers more than 2^63 nanoseconds in the future. This problem basically only affects programs which disable timer interrupts by setting the next one infinitely far in the future. However, the SBI doc specifically says that this is a valid approach, so it should be supported. Using the MSB doesn't work without changing code functionality in QEMU, but it should be sufficient to cap `next` at the maximum signed value.