From 15b8ed1a6a5962c66da0b8209bc181c45c7aa98d Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Wed, 15 Feb 2017 16:00:43 -0800 Subject: [PATCH] arcv2_timer: fix cycle count race It's possible the timer interrupt could occur when performing the computation, resulting in incorrect values returned. It's still possible for bad values to be returned if the function is called with interrupts locked, but that is only fixable with a second timer source. Issue: ZEP-1546 Change-Id: I16d5b04c3e32377f7249eb4fb1bf2f7c22bd0836 Signed-off-by: Andrew Boie --- drivers/timer/arcv2_timer0.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/timer/arcv2_timer0.c b/drivers/timer/arcv2_timer0.c index 3a681fb2faa..8144f1e4ca0 100644 --- a/drivers/timer/arcv2_timer0.c +++ b/drivers/timer/arcv2_timer0.c @@ -66,7 +66,7 @@ /* running total of timer count */ static uint32_t __noinit cycles_per_tick; -static uint32_t accumulated_cycle_count; +static volatile uint32_t accumulated_cycle_count; #ifdef CONFIG_TICKLESS_IDLE static uint32_t __noinit max_system_ticks; @@ -415,7 +415,14 @@ int sys_clock_device_ctrl(struct device *port, uint32_t ctrl_command, uint32_t _timer_cycle_get_32(void) { - return (accumulated_cycle_count + timer0_count_register_get()); + uint32_t acc, count; + + do { + acc = accumulated_cycle_count; + count = timer0_count_register_get(); + } while (acc != accumulated_cycle_count); + + return acc + count; } #if defined(CONFIG_SYSTEM_CLOCK_DISABLE)