Skip to content

Commit aa98876

Browse files
avpatelpalmer-dabbelt
authored andcommitted
RISC-V: Check clint_time_val before use
The NoMMU kernel is broken for QEMU virt machine from Linux-5.9-rc6 because clint_time_val is used even before CLINT driver is probed at following places: 1. rand_initialize() calls get_cycles() which in-turn uses clint_time_val 2. boot_init_stack_canary() calls get_cycles() which in-turn uses clint_time_val The issue#1 (above) is fixed by providing custom random_get_entropy() for RISC-V NoMMU kernel. For issue#2 (above), we remove dependency of boot_init_stack_canary() on get_cycles() and this is aligned with the boot_init_stack_canary() implementations of ARM, ARM64 and MIPS kernel. Fixes: d5be89a ("RISC-V: Resurrect the MMIO timer implementation for M-mode systems") Signed-off-by: Anup Patel <[email protected]> Tested-by: Damien Le Moal <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent c14decf commit aa98876

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

arch/riscv/include/asm/stackprotector.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#include <linux/random.h>
77
#include <linux/version.h>
8-
#include <asm/timex.h>
98

109
extern unsigned long __stack_chk_guard;
1110

@@ -18,12 +17,9 @@ extern unsigned long __stack_chk_guard;
1817
static __always_inline void boot_init_stack_canary(void)
1918
{
2019
unsigned long canary;
21-
unsigned long tsc;
2220

2321
/* Try to get a semi random initial value. */
2422
get_random_bytes(&canary, sizeof(canary));
25-
tsc = get_cycles();
26-
canary += tsc + (tsc << BITS_PER_LONG/2);
2723
canary ^= LINUX_VERSION_CODE;
2824
canary &= CANARY_MASK;
2925

arch/riscv/include/asm/timex.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ static inline u32 get_cycles_hi(void)
3333
#define get_cycles_hi get_cycles_hi
3434
#endif /* CONFIG_64BIT */
3535

36+
/*
37+
* Much like MIPS, we may not have a viable counter to use at an early point
38+
* in the boot process. Unfortunately we don't have a fallback, so instead
39+
* we just return 0.
40+
*/
41+
static inline unsigned long random_get_entropy(void)
42+
{
43+
if (unlikely(clint_time_val == NULL))
44+
return 0;
45+
return get_cycles();
46+
}
47+
#define random_get_entropy() random_get_entropy()
48+
3649
#else /* CONFIG_RISCV_M_MODE */
3750

3851
static inline cycles_t get_cycles(void)

0 commit comments

Comments
 (0)