diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2023-08-08 14:19:49 +1000 |
---|---|---|
committer | Cédric Le Goater <clg@kaod.org> | 2023-09-06 11:19:33 +0200 |
commit | 8e0a5ac87800ccc6dd5013f89f27652f4480ab33 (patch) | |
tree | f7d34dc846d0e87c99ef4fad66215f92137e805b /hw/virtio/virtio-input-host-pci.c | |
parent | eab0888418ab44344864965193cf6cd194ab6858 (diff) | |
download | qemu-8e0a5ac87800ccc6dd5013f89f27652f4480ab33.zip qemu-8e0a5ac87800ccc6dd5013f89f27652f4480ab33.tar.gz qemu-8e0a5ac87800ccc6dd5013f89f27652f4480ab33.tar.bz2 |
hw/ppc: Avoid decrementer rounding errors
The decrementer register contains a relative time in timebase units.
When writing to DECR this is converted and stored as an absolute value
in nanosecond units, reading DECR converts back to relative timebase.
The tb<->ns conversion of the relative part can cause rounding such that
a value writen to the decrementer can read back a different, with time
held constant. This is a particular problem for a deterministic icount
and record-replay trace.
Fix this by storing the absolute value in timebase units rather than
nanoseconds. The math before:
store: decr_next = now_ns + decr * ns_per_sec / tb_per_sec
load: decr = (decr_next - now_ns) * tb_per_sec / ns_per_sec
load(store): decr = decr * ns_per_sec / tb_per_sec * tb_per_sec /
ns_per_sec
After:
store: decr_next = now_ns * tb_per_sec / ns_per_sec + decr
load: decr = decr_next - now_ns * tb_per_sec / ns_per_sec
load(store): decr = decr
Fixes: 9fddaa0c0cab ("PowerPC merge: real time TB and decrementer - faster and simpler exception handling (Jocelyn Mayer)")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'hw/virtio/virtio-input-host-pci.c')
0 files changed, 0 insertions, 0 deletions