aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrey Bokhanko <andreybokhanko@gmail.com>2025-01-31 16:59:02 +0300
committerGopher Robot <gobot@golang.org>2025-02-17 18:02:01 -0800
commit81c66e71d480ae2372b7eea4bcdf600b50fdd5e1 (patch)
tree12d2327193452c1a34d9221483051d0ad97a7089 /src
parentd524e1eccd559b40130c3bac77f3f7dc33d476ab (diff)
downloadgo-81c66e71d480ae2372b7eea4bcdf600b50fdd5e1.tar.xz
runtime: check LSE support on ARM64 at runtime init
Check presence of LSE support on ARM64 chip if we targeted it at compile time. Related to #69124 Updates #60905 Fixes #71411 Change-Id: I65e899a28ff64a390182572c0c353aa5931fc85d Reviewed-on: https://go-review.googlesource.com/c/go/+/645795 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/asm_arm64.s50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s
index 64a1880589..bf9ab6bcbc 100644
--- a/src/runtime/asm_arm64.s
+++ b/src/runtime/asm_arm64.s
@@ -8,6 +8,28 @@
#include "funcdata.h"
#include "textflag.h"
+#ifdef GOARM64_LSE
+DATA no_lse_msg<>+0x00(SB)/64, $"This program can only run on ARM64 processors with LSE support.\n"
+GLOBL no_lse_msg<>(SB), RODATA, $64
+#endif
+
+// We know for sure that Linux and FreeBSD allow to read instruction set
+// attribute registers (while some others OSes, like OpenBSD and Darwin,
+// are not). Let's be conservative and allow code reading such registers
+// only when we sure this won't lead to sigill.
+#ifdef GOOS_linux
+#define ISA_REGS_READABLE
+#endif
+#ifdef GOOS_freebsd
+#define ISA_REGS_READABLE
+#endif
+
+#ifdef GOARM64_LSE
+#ifdef ISA_REGS_READABLE
+#define CHECK_GOARM64_LSE
+#endif
+#endif
+
TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
// SP = stack; R0 = argc; R1 = argv
@@ -77,6 +99,19 @@ nocgo:
BL runtime·wintls(SB)
#endif
+ // Check that CPU we use for execution supports instructions targeted during compile-time.
+#ifdef CHECK_GOARM64_LSE
+ // Read the ID_AA64ISAR0_EL1 register
+ MRS ID_AA64ISAR0_EL1, R0
+
+ // Extract the LSE field (bits [23:20])
+ LSR $20, R0, R0
+ AND $0xf, R0, R0
+
+ // LSE support is indicated by a non-zero value
+ CBZ R0, no_lse
+#endif
+
MOVW 8(RSP), R0 // copy argc
MOVW R0, -8(RSP)
MOVD 16(RSP), R0 // copy argv
@@ -95,6 +130,21 @@ nocgo:
// start this M
BL runtime·mstart(SB)
+ UNDEF
+
+#ifdef CHECK_GOARM64_LSE
+no_lse:
+ MOVD $1, R0 // stderr
+ MOVD R0, 8(RSP)
+ MOVD $no_lse_msg<>(SB), R1 // message address
+ MOVD R1, 16(RSP)
+ MOVD $64, R2 // message length
+ MOVD R2, 24(RSP)
+ CALL runtime·write(SB)
+ CALL runtime·exit(SB)
+ CALL runtime·abort(SB)
+ RET
+#endif
// Prevent dead-code elimination of debugCallV2 and debugPinnerV1, which are
// intended to be called by debuggers.