Index | Thread | Search

From:
Nick Owens <mischief@offblast.org>
Subject:
riscv64: explicitly enable u-mode timer access
To:
tech@openbsd.org
Date:
Sun, 12 Jul 2026 21:14:49 -0700

Download raw body.

Thread
  • Nick Owens:

    riscv64: explicitly enable u-mode timer access

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. */