mirror_qemu/hw/timer
Peter Maydell 04de6cb002 hw/timer/nrf51_timer: Don't lose time when timer is queried in tight loop
The nrf51_timer has a free-running counter which we implement using
the pattern of using two fields (update_counter_ns, counter) to track
the last point at which we calculated the counter value, and the
counter value at that time.  Then we can find the current counter
value by converting the difference in wall-clock time between then
and now to a tick count that we need to add to the counter value.

Unfortunately the nrf51_timer's implementation of this has a bug
which means it loses time every time update_counter() is called.
After updating s->counter it always sets s->update_counter_ns to
'now', even though the actual point when s->counter hit the new value
will be some point in the past (half a tick, say).  In the worst case
(guest code in a tight loop reading the counter, icount mode) the
counter is continually queried less than a tick after it was last
read, so s->counter never advances but s->update_counter_ns does, and
the guest never makes forward progress.

The fix for this is to only advance update_counter_ns to the
timestamp of the last tick, not all the way to 'now'.  (This is the
pattern used in hw/misc/mps2-fpgaio.c's counter.)

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Message-id: 20230606134917.3782215-1-peter.maydell@linaro.org
(cherry picked from commit d2f9a79a8c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-06-22 10:38:38 +03:00
..
Kconfig hw/timer: Add SiFive PWM support 2021-09-21 07:56:49 +10:00
a9gtimer.c hw/timer: fix a9gtimer vmstate 2022-02-21 13:30:21 +00:00
allwinner-a10-pit.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
altera_timer.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
arm_mptimer.c qdev: set properties with device_class_set_props() 2020-01-24 20:59:15 +01:00
arm_timer.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
armv7m_systick.c hw/timer/armv7m_systick: Update clock source before enabling timer 2022-02-08 10:56:28 +00:00
aspeed_timer.c aspeed/timer: Add AST1030 support 2022-05-02 17:03:03 +02:00
avr_timer16.c hw/timer: avr: Add limited support for 16-bit timer peripheral 2020-07-11 11:02:05 +02:00
bcm2835_systmr.c hw/timer/bcm2835: Support the timer COMPARE registers 2020-10-20 16:12:00 +01:00
cadence_ttc.c timer: cadence_ttc: Break out header file to allow embedding 2022-04-21 11:37:03 +01:00
cmsdk-apb-dualtimer.c clock: Add ClockEvent parameter to callbacks 2021-03-08 17:20:01 +00:00
cmsdk-apb-timer.c clock: Add ClockEvent parameter to callbacks 2021-03-08 17:20:01 +00:00
digic-timer.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
etraxfs_timer.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
exynos4210_mct.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
exynos4210_pwm.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
grlib_gptimer.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
hpet.c hw/timer/hpet: Fix expiration time overflow 2023-03-29 10:20:04 +03:00
i8254.c hw/i8254: fix vmstate load 2021-03-16 14:30:30 -04:00
i8254_common.c hw/i386: Remove obsolete LoadStateHandler::load_state_old handlers 2019-11-05 23:33:12 +01:00
ibex_timer.c hw/intc: Move mtimer/mtimecmp to aclint 2022-09-07 09:19:10 +02:00
imx_epit.c target/imx: reload cmp timer outside of the reload ptimer transaction 2022-10-27 10:27:23 +01:00
imx_gpt.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
meson.build hw/timer: Add SiFive PWM support 2021-09-21 07:56:49 +10:00
mips_gictimer.c hw: Do not include hw/sysbus.h if it is not necessary 2021-05-02 17:24:50 +02:00
mss-timer.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
npcm7xx_timer.c hw/timer/npcm7xx_timer: Use new clock_ns_to_ticks() 2021-03-08 17:20:01 +00:00
nrf51_timer.c hw/timer/nrf51_timer: Don't lose time when timer is queried in tight loop 2023-06-22 10:38:38 +03:00
omap_gptimer.c Include hw/hw.h exactly where needed 2019-08-16 13:31:52 +02:00
omap_synctimer.c Include hw/hw.h exactly where needed 2019-08-16 13:31:52 +02:00
pxa2xx_timer.c Use OBJECT_DECLARE_SIMPLE_TYPE when possible 2020-09-18 14:12:32 -04:00
renesas_cmt.c treewide: Remove the unnecessary space before semicolon 2022-10-24 13:41:10 +02:00
renesas_tmr.c treewide: Remove the unnecessary space before semicolon 2022-10-24 13:41:10 +02:00
sh_timer.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
sifive_pwm.c hw/timer: Add SiFive PWM support 2021-09-21 07:56:49 +10:00
slavio_timer.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00
sse-counter.c hw: Do not include hw/irq.h if it is not necessary 2021-05-02 17:24:50 +02:00
sse-timer.c Fix 'writeable' typos 2022-06-08 19:38:47 +01:00
stellaris-gptm.c hw/timer/stellaris-gptm: Use Clock input instead of system_clock_scale 2021-09-01 11:08:20 +01:00
stm32f2xx_timer.c hw/timer/stm32f2xx_timer: Remove dead assignment 2020-05-04 14:43:24 +02:00
trace-events hw/sh4: Change debug printfs to traces 2021-10-30 18:39:37 +02:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
xilinx_timer.c ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY 2022-05-19 16:19:03 +01:00