diff options
| author | Mark Ryan <markdryan@rivosinc.com> | 2023-08-25 11:22:02 +0200 |
|---|---|---|
| committer | Joel Sing <joel@sing.id.au> | 2025-02-05 03:47:25 -0800 |
| commit | bcfa00cbd259a8653547b227f8207ab43bf7d5c8 (patch) | |
| tree | 54b531e1e8d252bed4e950463456c33a30e912f8 /src/runtime | |
| parent | 664aebab7da0da5859857c60b401ec85e3a408dd (diff) | |
| download | go-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.go | 30 |
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 +} |
