mirror of
https://github.com/golang/go
synced 2024-11-12 07:00:21 -07:00
runtime: check amd64 microarchitecture level at startup
Make Go runtime throw if it's been compiled to assume instruction
set extensions that aren't available on the CPU.
Updates #48506
Change-Id: Ic4d6696e1cd6b28d389a86fe64e8175ea3ca135a
GitHub-Last-Rev: ba338377f5
GitHub-Pull-Request: golang/go#48514
Reviewed-on: https://go-review.googlesource.com/c/go/+/351191
Run-TryBot: Martin Möhrmann <martin@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Martin Möhrmann <martin@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Martin Möhrmann <martin@golang.org>
This commit is contained in:
parent
58fb05a24a
commit
8c8baad927
@ -78,6 +78,87 @@ GLOBL _rt0_amd64_lib_argc<>(SB),NOPTR, $8
|
||||
DATA _rt0_amd64_lib_argv<>(SB)/8, $0
|
||||
GLOBL _rt0_amd64_lib_argv<>(SB),NOPTR, $8
|
||||
|
||||
#ifdef GOAMD64_v2
|
||||
DATA bad_cpu_msg<>+0x00(SB)/84, $"This program can only be run on AMD64 processors with v2 microarchitecture support.\n"
|
||||
#endif
|
||||
|
||||
#ifdef GOAMD64_v3
|
||||
DATA bad_cpu_msg<>+0x00(SB)/84, $"This program can only be run on AMD64 processors with v3 microarchitecture support.\n"
|
||||
#endif
|
||||
|
||||
#ifdef GOAMD64_v4
|
||||
DATA bad_cpu_msg<>+0x00(SB)/84, $"This program can only be run on AMD64 processors with v4 microarchitecture support.\n"
|
||||
#endif
|
||||
|
||||
GLOBL bad_cpu_msg<>(SB), RODATA, $84
|
||||
|
||||
// Define a list of AMD64 microarchitecture level features
|
||||
// https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
|
||||
|
||||
// SSE3 SSSE3 CMPXCHNG16 SSE4.1 SSE4.2 POPCNT
|
||||
#define V2_FEATURES_CX (1 << 0 | 1 << 9 | 1 << 13 | 1 << 19 | 1 << 20 | 1 << 23)
|
||||
// LAHF/SAHF
|
||||
#define V2_EXT_FEATURES_CX (1 << 0)
|
||||
// FMA MOVBE OSXSAVE AVX F16C
|
||||
#define V3_FEATURES_CX (V2_FEATURES_CX | 1 << 12 | 1 << 22 | 1 << 27 | 1 << 28 | 1 << 29)
|
||||
// ABM (FOR LZNCT)
|
||||
#define V3_EXT_FEATURES_CX (V2_EXT_FEATURES_CX | 1 << 5)
|
||||
// BMI1 AVX2 BMI2
|
||||
#define V3_EXT_FEATURES_BX (1 << 3 | 1 << 5 | 1 << 8)
|
||||
// XMM YMM
|
||||
#define V3_OS_SUPPORT_AX (1 << 1 | 1 << 2)
|
||||
|
||||
#define V4_FEATURES_CX V3_FEATURES_CX
|
||||
|
||||
#define V4_EXT_FEATURES_CX V3_EXT_FEATURES_CX
|
||||
// AVX512F AVX512DQ AVX512CD AVX512BW AVX512VL
|
||||
#define V4_EXT_FEATURES_BX (V3_EXT_FEATURES_BX | 1 << 16 | 1 << 17 | 1 << 28 | 1 << 30 | 1 << 31)
|
||||
// OPMASK ZMM
|
||||
#define V4_OS_SUPPORT_AX (V3_OS_SUPPORT_AX | 1 << 5 | (1 << 6 | 1 << 7))
|
||||
|
||||
#ifdef GOAMD64_v2
|
||||
#define NEED_MAX_CPUID 0x80000001
|
||||
#define NEED_FEATURES_CX V2_FEATURES_CX
|
||||
#define NEED_EXT_FEATURES_CX V2_EXT_FEATURES_CX
|
||||
#endif
|
||||
|
||||
#ifdef GOAMD64_v3
|
||||
#define NEED_MAX_CPUID 0x80000001
|
||||
#define NEED_FEATURES_CX V3_FEATURES_CX
|
||||
#define NEED_EXT_FEATURES_CX V3_EXT_FEATURES_CX
|
||||
#define NEED_EXT_FEATURES_BX V3_EXT_FEATURES_BX
|
||||
#define NEED_OS_SUPPORT_AX V3_OS_SUPPORT_AX
|
||||
#endif
|
||||
|
||||
#ifdef GOAMD64_v4
|
||||
#define NEED_MAX_CPUID 0x80000001
|
||||
#define NEED_FEATURES_CX V4_FEATURES_CX
|
||||
#define NEED_EXT_FEATURES_CX V4_EXT_FEATURES_CX
|
||||
#define NEED_EXT_FEATURES_BX V4_EXT_FEATURES_BX
|
||||
|
||||
// Downgrading v4 OS checks on Darwin for now, see CL 285572.
|
||||
#ifdef GOOS_darwin
|
||||
#define NEED_OS_SUPPORT_AX V3_OS_SUPPORT_AX
|
||||
#else
|
||||
#define NEED_OS_SUPPORT_AX V4_OS_SUPPORT_AX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef GOAMD64_v1
|
||||
#define SKIP_GOAMD64_CHECK
|
||||
#endif
|
||||
|
||||
#ifndef GOAMD64_v1
|
||||
#ifndef GOAMD64_v2
|
||||
#ifndef GOAMD64_v3
|
||||
#ifndef GOAMD64_v4
|
||||
#define SKIP_GOAMD64_CHECK
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
|
||||
// copy arguments forward on an even stack
|
||||
MOVQ DI, AX // argc
|
||||
@ -99,10 +180,24 @@ TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
|
||||
// find out information about the processor we're on
|
||||
MOVL $0, AX
|
||||
CPUID
|
||||
MOVL AX, SI
|
||||
CMPL AX, $0
|
||||
#ifdef SKIP_GOAMD64_CHECK
|
||||
JE nocpuinfo
|
||||
#else
|
||||
JNE has_cpuinfo
|
||||
|
||||
bad_cpu: // show that the program requires a certain microarchitecture level.
|
||||
MOVQ $2, 0(SP)
|
||||
MOVQ $bad_cpu_msg<>(SB), AX
|
||||
MOVQ AX, 8(SP)
|
||||
MOVQ $84, 16(SP)
|
||||
CALL runtime·write(SB)
|
||||
MOVQ $1, 0(SP)
|
||||
CALL runtime·exit(SB)
|
||||
CALL runtime·abort(SB)
|
||||
#endif
|
||||
|
||||
has_cpuinfo:
|
||||
CMPL BX, $0x756E6547 // "Genu"
|
||||
JNE notintel
|
||||
CMPL DX, $0x49656E69 // "ineI"
|
||||
@ -110,13 +205,51 @@ TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
|
||||
CMPL CX, $0x6C65746E // "ntel"
|
||||
JNE notintel
|
||||
MOVB $1, runtime·isIntel(SB)
|
||||
notintel:
|
||||
|
||||
notintel:
|
||||
// Load EAX=1 cpuid flags
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
MOVL AX, runtime·processorVersionInfo(SB)
|
||||
|
||||
#ifdef NEED_FEATURES_CX
|
||||
ANDL $NEED_FEATURES_CX, CX
|
||||
CMPL CX, $NEED_FEATURES_CX
|
||||
JNE bad_cpu
|
||||
#endif
|
||||
|
||||
#ifdef NEED_MAX_CPUID
|
||||
MOVL $0x80000000, AX
|
||||
CPUID
|
||||
CMPL AX, $NEED_MAX_CPUID
|
||||
JL bad_cpu
|
||||
#endif
|
||||
|
||||
#ifdef NEED_EXT_FEATURES_BX
|
||||
MOVL $7, AX
|
||||
MOVL $0, CX
|
||||
CPUID
|
||||
ANDL $NEED_EXT_FEATURES_BX, BX
|
||||
CMPL BX, $NEED_EXT_FEATURES_BX
|
||||
JNE bad_cpu
|
||||
#endif
|
||||
|
||||
#ifdef NEED_EXT_FEATURES_CX
|
||||
MOVL $0x80000001, AX
|
||||
CPUID
|
||||
ANDL $NEED_EXT_FEATURES_CX, CX
|
||||
CMPL CX, $NEED_EXT_FEATURES_CX
|
||||
JNE bad_cpu
|
||||
#endif
|
||||
|
||||
#ifdef NEED_OS_SUPPORT_AX
|
||||
XORL CX, CX
|
||||
XGETBV
|
||||
ANDL $NEED_OS_SUPPORT_AX, AX
|
||||
CMPL AX, $NEED_OS_SUPPORT_AX
|
||||
JNE bad_cpu
|
||||
#endif
|
||||
|
||||
nocpuinfo:
|
||||
// if there is an _cgo_init, call it.
|
||||
MOVQ _cgo_init(SB), AX
|
||||
|
Loading…
Reference in New Issue
Block a user