1
0
mirror of https://github.com/golang/go synced 2024-11-12 07:40:23 -07:00

internal/cpu: disable FMA when OSXSAVE is not enabled on x86

All instructions in the FMA extension on x86 are VEX prefixed.
VEX prefixed instructions generally require OSXSAVE to be enabled.

The execution of FMA instructions emitted by the Go compiler on amd64
will generate an invalid opcode exception if OSXSAVE is not enabled.

Fixes #41022

Change-Id: I49881630e7195c804110a2bd81b5bec8cac31ba8
Reviewed-on: https://go-review.googlesource.com/c/go/+/274479
Trust: Martin Möhrmann <moehrmann@google.com>
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Martin Möhrmann 2020-12-03 16:41:57 +01:00
parent 58768ae15b
commit dda2991c2e

View File

@ -75,13 +75,22 @@ func doinit() {
X86.HasSSE3 = isSet(ecx1, cpuid_SSE3) X86.HasSSE3 = isSet(ecx1, cpuid_SSE3)
X86.HasPCLMULQDQ = isSet(ecx1, cpuid_PCLMULQDQ) X86.HasPCLMULQDQ = isSet(ecx1, cpuid_PCLMULQDQ)
X86.HasSSSE3 = isSet(ecx1, cpuid_SSSE3) X86.HasSSSE3 = isSet(ecx1, cpuid_SSSE3)
X86.HasFMA = isSet(ecx1, cpuid_FMA)
X86.HasSSE41 = isSet(ecx1, cpuid_SSE41) X86.HasSSE41 = isSet(ecx1, cpuid_SSE41)
X86.HasSSE42 = isSet(ecx1, cpuid_SSE42) X86.HasSSE42 = isSet(ecx1, cpuid_SSE42)
X86.HasPOPCNT = isSet(ecx1, cpuid_POPCNT) X86.HasPOPCNT = isSet(ecx1, cpuid_POPCNT)
X86.HasAES = isSet(ecx1, cpuid_AES) X86.HasAES = isSet(ecx1, cpuid_AES)
// OSXSAVE can be false when using older Operating Systems
// or when explicitly disabled on newer Operating Systems by
// e.g. setting the xsavedisable boot option on Windows 10.
X86.HasOSXSAVE = isSet(ecx1, cpuid_OSXSAVE) X86.HasOSXSAVE = isSet(ecx1, cpuid_OSXSAVE)
// The FMA instruction set extension only has VEX prefixed instructions.
// VEX prefixed instructions require OSXSAVE to be enabled.
// See Intel 64 and IA-32 Architecture Software Developers Manual Volume 2
// Section 2.4 "AVX and SSE Instruction Exception Specification"
X86.HasFMA = isSet(ecx1, cpuid_FMA) && X86.HasOSXSAVE
osSupportsAVX := false osSupportsAVX := false
// For XGETBV, OSXSAVE bit is required and sufficient. // For XGETBV, OSXSAVE bit is required and sufficient.
if X86.HasOSXSAVE { if X86.HasOSXSAVE {