mirror of https://github.com/torvalds/linux.git
On RV32, updating the 64-bit stimecmp (or vstimecmp) CSR requires two
separate 32-bit writes. A race condition exists if the timer triggers
during these two writes.
The RISC-V Privileged Specification (e.g., Section 3.2.1 for mtimecmp)
recommends a specific 3-step sequence to avoid spurious interrupts
when updating 64-bit comparison registers on 32-bit systems:
1. Set the low-order bits (stimecmp) to all ones (ULONG_MAX).
2. Set the high-order bits (stimecmph) to the desired value.
3. Set the low-order bits (stimecmp) to the desired value.
Current implementation writes the LSB first without ensuring a future
value, which may lead to a transient state where the 64-bit comparison
is incorrectly evaluated as "expired" by the hardware. This results in
spurious timer interrupts.
This patch adopts the spec-recommended 3-step sequence to ensure the
intermediate 64-bit state is never smaller than the current time.
Fixes:
|
||
|---|---|---|
| .. | ||
| Kconfig | ||
| Makefile | ||
| acpi_pm.c | ||
| arc_timer.c | ||
| arm_arch_timer.c | ||
| arm_arch_timer_mmio.c | ||
| arm_global_timer.c | ||
| armv7m_systick.c | ||
| asm9260_timer.c | ||
| bcm2835_timer.c | ||
| bcm_kona_timer.c | ||
| clksrc-dbx500-prcmu.c | ||
| clksrc_st_lpc.c | ||
| clps711x-timer.c | ||
| dummy_timer.c | ||
| dw_apb_timer.c | ||
| dw_apb_timer_of.c | ||
| em_sti.c | ||
| exynos_mct.c | ||
| hyperv_timer.c | ||
| i8253.c | ||
| ingenic-ost.c | ||
| ingenic-sysost.c | ||
| ingenic-timer.c | ||
| jcore-pit.c | ||
| mips-gic-timer.c | ||
| mmio.c | ||
| mps2-timer.c | ||
| mxs_timer.c | ||
| nomadik-mtu.c | ||
| numachip.c | ||
| renesas-ostm.c | ||
| samsung_pwm_timer.c | ||
| scx200_hrt.c | ||
| sh_cmt.c | ||
| sh_mtu2.c | ||
| sh_tmu.c | ||
| timer-armada-370-xp.c | ||
| timer-atmel-pit.c | ||
| timer-atmel-st.c | ||
| timer-atmel-tcb.c | ||
| timer-cadence-ttc.c | ||
| timer-clint.c | ||
| timer-cs5535.c | ||
| timer-davinci.c | ||
| timer-digicolor.c | ||
| timer-econet-en751221.c | ||
| timer-ep93xx.c | ||
| timer-fsl-ftm.c | ||
| timer-fttmr010.c | ||
| timer-goldfish.c | ||
| timer-gx6605s.c | ||
| timer-gxp.c | ||
| timer-imx-gpt.c | ||
| timer-imx-sysctr.c | ||
| timer-imx-tpm.c | ||
| timer-integrator-ap.c | ||
| timer-ixp4xx.c | ||
| timer-keystone.c | ||
| timer-loongson1-pwm.c | ||
| timer-lpc32xx.c | ||
| timer-mediatek-cpux.c | ||
| timer-mediatek.c | ||
| timer-meson6.c | ||
| timer-microchip-pit64b.c | ||
| timer-milbeaut.c | ||
| timer-mp-csky.c | ||
| timer-msc313e.c | ||
| timer-npcm7xx.c | ||
| timer-nxp-pit.c | ||
| timer-nxp-stm.c | ||
| timer-of.c | ||
| timer-of.h | ||
| timer-orion.c | ||
| timer-owl.c | ||
| timer-pistachio.c | ||
| timer-probe.c | ||
| timer-pxa.c | ||
| timer-qcom.c | ||
| timer-ralink.c | ||
| timer-rda.c | ||
| timer-realtek.c | ||
| timer-riscv.c | ||
| timer-rockchip.c | ||
| timer-rtl-otto.c | ||
| timer-sp.h | ||
| timer-sp804.c | ||
| timer-sprd.c | ||
| timer-stm32-lp.c | ||
| timer-stm32.c | ||
| timer-sun4i.c | ||
| timer-sun5i.c | ||
| timer-tegra.c | ||
| timer-tegra186.c | ||
| timer-ti-32k.c | ||
| timer-ti-dm-systimer.c | ||
| timer-ti-dm.c | ||
| timer-versatile.c | ||
| timer-vt8500.c | ||
| timer-zevio.c | ||