summary refs log tree commit diff stats
path: root/results/classifier/118/architecture-risc-v/493
blob: 21e555eaf61a67d3ebf1bbe82424c2597510f0da (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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.