aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorMark Ryan <markdryan@rivosinc.com>2023-08-25 11:22:02 +0200
committerJoel Sing <joel@sing.id.au>2025-02-05 03:47:25 -0800
commitbcfa00cbd259a8653547b227f8207ab43bf7d5c8 (patch)
tree54b531e1e8d252bed4e950463456c33a30e912f8 /src/runtime
parent664aebab7da0da5859857c60b401ec85e3a408dd (diff)
downloadgo-bcfa00cbd259a8653547b227f8207ab43bf7d5c8.tar.xz
cpu/internal: provide runtime detection of RISC-V extensions on Linux
Add a RISCV64 variable to cpu/internal that indicates both the presence of RISC-V extensions and performance information about the underlying RISC-V cores. The variable is only populated with non false values on Linux. The detection code relies on the riscv_hwprobe syscall introduced in Linux 6.4. The patch can detect RVV 1.0 and whether the CPU supports fast misaligned accesses. It can only detect RVV 1.0 on a 6.5 kernel or later (without backports). Updates #61416 Change-Id: I2d8289345c885b699afff441d417cae38f6bdc54 Reviewed-on: https://go-review.googlesource.com/c/go/+/522995 Reviewed-by: Joel Sing <joel@sing.id.au> Reviewed-by: Meng Zhuo <mengzhuo1203@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/os_linux_riscv64.go30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/runtime/os_linux_riscv64.go b/src/runtime/os_linux_riscv64.go
index 9be88a5ad2..c4a4d4e50d 100644
--- a/src/runtime/os_linux_riscv64.go
+++ b/src/runtime/os_linux_riscv64.go
@@ -4,4 +4,34 @@
package runtime
+import (
+ "internal/runtime/syscall"
+ "unsafe"
+)
+
func osArchInit() {}
+
+type riscvHWProbePairs = struct {
+ key int64
+ value uint64
+}
+
+// TODO: Consider whether to use the VDSO entry for riscv_hwprobe.
+// There is a VDSO entry for riscv_hwprobe that should allow us to avoid the syscall
+// entirely as it can handle the case where the caller only requests extensions that are
+// supported on all cores, which is what we're doing here. However, as we're only calling
+// this syscall once, it may not be worth the added effort to implement the VDSO call.
+
+//go:linkname internal_cpu_riscvHWProbe internal/cpu.riscvHWProbe
+func internal_cpu_riscvHWProbe(pairs []riscvHWProbePairs, flags uint) bool {
+ // sys_RISCV_HWPROBE is copied from golang.org/x/sys/unix/zsysnum_linux_riscv64.go.
+ const sys_RISCV_HWPROBE uintptr = 258
+
+ if len(pairs) == 0 {
+ return false
+ }
+ // Passing in a cpuCount of 0 and a cpu of nil ensures that only extensions supported by all the
+ // cores are returned, which is the behaviour we want in internal/cpu.
+ _, _, e1 := syscall.Syscall6(sys_RISCV_HWPROBE, uintptr(unsafe.Pointer(&pairs[0])), uintptr(len(pairs)), uintptr(0), uintptr(unsafe.Pointer(nil)), uintptr(flags), 0)
+ return e1 == 0
+}