From: Andrey Bokhanko Date: Fri, 31 Jan 2025 13:59:02 +0000 (+0300) Subject: runtime: check LSE support on ARM64 at runtime init X-Git-Tag: go1.25rc1~1003 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=81c66e71d480ae2372b7eea4bcdf600b50fdd5e1;p=gostls13.git 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 LUCI-TryBot-Result: Go LUCI Auto-Submit: Dmitri Shuralyov --- 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.