From 5ccd8e5133a43e574be8d66aae3a230c39b4b67a Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 10 Mar 2022 15:26:22 -0800 Subject: [PATCH] internal/cpu: disallow disabling options that are required for microarch MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit e.g., if GOAMD64=v3, don't allow GODEBUG=cpu.XXX=off for XXX which are required for v3. Change-Id: Ib58a4c8b13c5464ba476448ba44bbb261218787c Reviewed-on: https://go-review.googlesource.com/c/go/+/391694 Trust: Keith Randall Run-TryBot: Keith Randall TryBot-Result: Gopher Robot Reviewed-by: Martin Möhrmann --- src/internal/cpu/cpu_x86.go | 34 ++++++++++++++++++++++++---------- src/internal/cpu/cpu_x86.s | 17 +++++++++++++++++ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/internal/cpu/cpu_x86.go b/src/internal/cpu/cpu_x86.go index 81d5ceed61..6fd979a747 100644 --- a/src/internal/cpu/cpu_x86.go +++ b/src/internal/cpu/cpu_x86.go @@ -14,6 +14,9 @@ func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) // xgetbv with ecx = 0 is implemented in cpu_x86.s. func xgetbv() (eax, edx uint32) +// getGOAMD64level is implemented in cpu_x86.s. Returns number in [1,4]. +func getGOAMD64level() int32 + const ( // edx bits cpuid_SSE2 = 1 << 26 @@ -47,19 +50,30 @@ func doinit() { options = []option{ {Name: "adx", Feature: &X86.HasADX}, {Name: "aes", Feature: &X86.HasAES}, - {Name: "avx", Feature: &X86.HasAVX}, - {Name: "avx2", Feature: &X86.HasAVX2}, - {Name: "bmi1", Feature: &X86.HasBMI1}, - {Name: "bmi2", Feature: &X86.HasBMI2}, {Name: "erms", Feature: &X86.HasERMS}, - {Name: "fma", Feature: &X86.HasFMA}, {Name: "pclmulqdq", Feature: &X86.HasPCLMULQDQ}, - {Name: "popcnt", Feature: &X86.HasPOPCNT}, {Name: "rdtscp", Feature: &X86.HasRDTSCP}, - {Name: "sse3", Feature: &X86.HasSSE3}, - {Name: "sse41", Feature: &X86.HasSSE41}, - {Name: "sse42", Feature: &X86.HasSSE42}, - {Name: "ssse3", Feature: &X86.HasSSSE3}, + } + level := getGOAMD64level() + if level < 2 { + // These options are required at level 2. At lower levels + // they can be turned off. + options = append(options, + option{Name: "popcnt", Feature: &X86.HasPOPCNT}, + option{Name: "sse3", Feature: &X86.HasSSE3}, + option{Name: "sse41", Feature: &X86.HasSSE41}, + option{Name: "sse42", Feature: &X86.HasSSE42}, + option{Name: "ssse3", Feature: &X86.HasSSSE3}) + } + if level < 3 { + // These options are required at level 3. At lower levels + // they can be turned off. + options = append(options, + option{Name: "avx", Feature: &X86.HasAVX}, + option{Name: "avx2", Feature: &X86.HasAVX2}, + option{Name: "bmi1", Feature: &X86.HasBMI1}, + option{Name: "bmi2", Feature: &X86.HasBMI2}, + option{Name: "fma", Feature: &X86.HasFMA}) } maxID, _, _, _ := cpuid(0, 0) diff --git a/src/internal/cpu/cpu_x86.s b/src/internal/cpu/cpu_x86.s index edef21905c..2ee8eca248 100644 --- a/src/internal/cpu/cpu_x86.s +++ b/src/internal/cpu/cpu_x86.s @@ -24,3 +24,20 @@ TEXT ·xgetbv(SB),NOSPLIT,$0-8 MOVL AX, eax+0(FP) MOVL DX, edx+4(FP) RET + +// func getGOAMD64level() int32 +TEXT ·getGOAMD64level(SB),NOSPLIT,$0-4 +#ifdef GOAMD64_v4 + MOVL $4, ret+0(FP) +#else +#ifdef GOAMD64_v3 + MOVL $3, ret+0(FP) +#else +#ifdef GOAMD64_v2 + MOVL $2, ret+0(FP) +#else + MOVL $1, ret+0(FP) +#endif +#endif +#endif + RET -- 2.50.0