]> www.infradead.org Git - users/dwmw2/qemu.git/commit
hw/ppc: Avoid decrementer rounding errors
authorNicholas Piggin <npiggin@gmail.com>
Tue, 8 Aug 2023 04:19:49 +0000 (14:19 +1000)
committerCédric Le Goater <clg@kaod.org>
Wed, 6 Sep 2023 09:19:33 +0000 (11:19 +0200)
commit8e0a5ac87800ccc6dd5013f89f27652f4480ab33
treef7d34dc846d0e87c99ef4fad66215f92137e805b
parenteab0888418ab44344864965193cf6cd194ab6858
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>
hw/ppc/ppc.c