From 803a4ff620384388a6297dbe0394b3cf76b1ff57 Mon Sep 17 00:00:00 2001 From: Jun Lin Date: Tue, 4 Jan 2022 14:16:29 +0800 Subject: [PATCH] driver: timer: npcx: fix the racing condition when getting current uptime In npcx_itim_evt_isr, it updates the cyc_sys_announced variable and then calls sys_clock_announce() to update the kernel curr_tick variable. If an ISR handler with higher priority preempts the timer ISR after the sys_clock_announce is updated and before the sys_clock_announce() is called, it will read the wrong time when calling k_uptime_get() because the cyc_sys_announced and the curr_tick are not synchronized. The commit fixes the problem by raising the timer's interrupt priority to the highest one (i.e. 1 in npcx's configuration). This commit also moves the computation of the delta cycle inside the spinlock in sys_clock_elapsed() to prevent another potential racing condition. Signed-off-by: Jun Lin Signed-off-by: Wealian Liao --- drivers/timer/npcx_itim_timer.c | 4 ++-- dts/arm/nuvoton/npcx7.dtsi | 2 +- dts/arm/nuvoton/npcx9.dtsi | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/timer/npcx_itim_timer.c b/drivers/timer/npcx_itim_timer.c index e1c83a29980..ca6788d7a28 100644 --- a/drivers/timer/npcx_itim_timer.c +++ b/drivers/timer/npcx_itim_timer.c @@ -249,12 +249,12 @@ uint32_t sys_clock_elapsed(void) } k_spinlock_key_t key = k_spin_lock(&lock); - uint64_t current = npcx_itim_get_sys_cyc64(); + uint64_t delta_cycle = npcx_itim_get_sys_cyc64() - cyc_sys_announced; k_spin_unlock(&lock, key); /* Return how many ticks elapsed since last sys_clock_announce() call */ - return (uint32_t)((current - cyc_sys_announced) / SYS_CYCLES_PER_TICK); + return (uint32_t)(delta_cycle / SYS_CYCLES_PER_TICK); } uint32_t sys_clock_cycle_get_32(void) diff --git a/dts/arm/nuvoton/npcx7.dtsi b/dts/arm/nuvoton/npcx7.dtsi index 97e650a0764..8f2e80c0d13 100644 --- a/dts/arm/nuvoton/npcx7.dtsi +++ b/dts/arm/nuvoton/npcx7.dtsi @@ -68,7 +68,7 @@ reg-names = "evt_itim", "sys_itim"; clocks = <&pcc NPCX_CLOCK_BUS_LFCLK NPCX_PWDWN_CTL4 3 &pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL7 5>; - interrupts = <46 2>; /* Event timer interrupt */ + interrupts = <46 1>; /* Event timer interrupt */ label = "ITIM"; }; diff --git a/dts/arm/nuvoton/npcx9.dtsi b/dts/arm/nuvoton/npcx9.dtsi index d05921309b2..296be5a2ba6 100644 --- a/dts/arm/nuvoton/npcx9.dtsi +++ b/dts/arm/nuvoton/npcx9.dtsi @@ -69,7 +69,7 @@ reg-names = "evt_itim", "sys_itim"; clocks = <&pcc NPCX_CLOCK_BUS_LFCLK NPCX_PWDWN_CTL4 0 &pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL7 5>; - interrupts = <28 2>; /* Event timer interrupt */ + interrupts = <28 1>; /* Event timer interrupt */ label = "ITIM"; };