The NoMMU kernel is broken for QEMU virt machine from Linux-5.9-rc6 because the get_cycles() and friends are called very early from rand_initialize() before CLINT driver is probed. To fix this, we should check clint_time_val before use in get_cycles() and friends.
Fixes: d5be89a8d118 ("RISC-V: Resurrect the MMIO timer implementation for M-mode systems") Signed-off-by: Anup Patel <anup.pa...@wdc.com> --- Changes since v1: - Explicitly initialize clint_time_val to NULL in CLINT driver to avoid hang on Kendryte K210 --- arch/riscv/include/asm/timex.h | 12 +++++++++--- drivers/clocksource/timer-clint.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h index 7f659dda0032..6e7b04874755 100644 --- a/arch/riscv/include/asm/timex.h +++ b/arch/riscv/include/asm/timex.h @@ -17,18 +17,24 @@ typedef unsigned long cycles_t; #ifdef CONFIG_64BIT static inline cycles_t get_cycles(void) { - return readq_relaxed(clint_time_val); + if (clint_time_val) + return readq_relaxed(clint_time_val); + return 0; } #else /* !CONFIG_64BIT */ static inline u32 get_cycles(void) { - return readl_relaxed(((u32 *)clint_time_val)); + if (clint_time_val) + return readl_relaxed(((u32 *)clint_time_val)); + return 0; } #define get_cycles get_cycles static inline u32 get_cycles_hi(void) { - return readl_relaxed(((u32 *)clint_time_val) + 1); + if (clint_time_val) + return readl_relaxed(((u32 *)clint_time_val) + 1); + return 0; } #define get_cycles_hi get_cycles_hi #endif /* CONFIG_64BIT */ diff --git a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c index d17367dee02c..8dbec85979fd 100644 --- a/drivers/clocksource/timer-clint.c +++ b/drivers/clocksource/timer-clint.c @@ -37,7 +37,7 @@ static unsigned long clint_timer_freq; static unsigned int clint_timer_irq; #ifdef CONFIG_RISCV_M_MODE -u64 __iomem *clint_time_val; +u64 __iomem *clint_time_val = NULL; #endif static void clint_send_ipi(const struct cpumask *target) -- 2.25.1