From: Nick Owens Subject: riscv64: explicitly enable u-mode timer access To: tech@openbsd.org Date: Sun, 12 Jul 2026 21:14:49 -0700 hi, with edk2 under linux kvm, it seems kvm sets scounteren register to 0 and edk2 doesn't enable scounteren.TM bit itself. because of that, attempts to read time in u-mode just get a SIGILL. since the register state is unspecified, we should explicitly enable scounteren.TM so that time works. diff --git a/sys/arch/riscv64/include/riscvreg.h b/sys/arch/riscv64/include/riscvreg.h index 38b750c65a3..4a78c210567 100644 --- a/sys/arch/riscv64/include/riscvreg.h +++ b/sys/arch/riscv64/include/riscvreg.h @@ -115,6 +115,10 @@ #define USTATUS_UIE (1 << 0) #define USTATUS_UPIE (1 << 4) +#define SCOUNTEREN_CY (1 << 0) +#define SCOUNTEREN_TM (1 << 1) +#define SCOUNTEREN_IR (1 << 2) + #define MSTATUS_PRV_U 0 /* user */ #define MSTATUS_PRV_S 1 /* supervisor */ #define MSTATUS_PRV_H 2 /* hypervisor */ diff --git a/sys/arch/riscv64/riscv64/cpu.c b/sys/arch/riscv64/riscv64/cpu.c index 9f83ed32ad6..a7b0df257f7 100644 --- a/sys/arch/riscv64/riscv64/cpu.c +++ b/sys/arch/riscv64/riscv64/cpu.c @@ -672,6 +672,7 @@ cpu_start_secondary(void) cpu_startclock(); csr_clear(sstatus, SSTATUS_FS_MASK | SSTATUS_VS_MASK); + csr_write(scounteren, SCOUNTEREN_TM); csr_set(sie, SIE_SSIE); atomic_setbits_int(&ci->ci_flags, CPUF_RUNNING); diff --git a/sys/arch/riscv64/riscv64/machdep.c b/sys/arch/riscv64/riscv64/machdep.c index d2d75165092..65dd7ff9db1 100644 --- a/sys/arch/riscv64/riscv64/machdep.c +++ b/sys/arch/riscv64/riscv64/machdep.c @@ -582,6 +582,8 @@ initriscv(struct riscv_bootparams *rbp) /* Set the per-CPU pointer. */ __asm volatile("mv tp, %0" :: "r"(&cpu_info_primary)); + csr_write(scounteren, SCOUNTEREN_TM); + sbi_init(); /* The bootloader has loaded us into a 64MB block. */