]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: check LSE support on ARM64 at runtime init
authorAndrey Bokhanko <andreybokhanko@gmail.com>
Fri, 31 Jan 2025 13:59:02 +0000 (16:59 +0300)
committerGopher Robot <gobot@golang.org>
Tue, 18 Feb 2025 02:02:01 +0000 (18:02 -0800)
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>

src/runtime/asm_arm64.s

index 64a1880589390d20b9c0fb77ec9b0628fb68f4cd..bf9ab6bcbced8ea1c1d2d4206a7cd13828d92f90 100644 (file)
@@ -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.