mirror of
https://github.com/golang/sys.git
synced 2026-01-29 07:02:06 +03:00
Darwin opmask clobbering bug was fixed in kernel version 21.3.0 as released in MacOS 12.2.0. This commit resolves issue by checking for Darwin AVX512 support via a sysctl call with the addition of a kernel minimum version check. The kernel version check is completed without adding new dependencies to x/sys/cpu. A sysctl call is accomplished by copying a minimal amount of code from x/sys/unix, to retrieve only the needed KERN_OSRELEASE value. This code is structured in the same manner as an existing analogous AIX/PPC64 syscall. The resulting dotted version string value is then parsed for numeric comparison with a dependency free function. All code in this contribution is structured to ease removal of the special darwin/amd64 codepaths when that OS/arch combination is eventually no longer supported by golang. Resolves issue: golang/go#49233, reinstates fix for issue: golang/go#43089 Change-Id: I4755fc8b3865eb6562b0959ecc910e2c46ac6cb4 Reviewed-on: https://go-review.googlesource.com/c/sys/+/620256 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Carlos Amedee <carlos@golang.org> Reviewed-by: vsivsi@yahoo.com <vsivsi@yahoo.com>
62 lines
2.1 KiB
Go
62 lines
2.1 KiB
Go
// Copyright 2024 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
//go:build darwin && amd64 && gc
|
|
|
|
package cpu
|
|
|
|
// darwinSupportsAVX512 checks Darwin kernel for AVX512 support via sysctl
|
|
// call (see issue 43089). It also restricts AVX512 support for Darwin to
|
|
// kernel version 21.3.0 (MacOS 12.2.0) or later (see issue 49233).
|
|
//
|
|
// Background:
|
|
// Darwin implements a special mechanism to economize on thread state when
|
|
// AVX512 specific registers are not in use. This scheme minimizes state when
|
|
// preempting threads that haven't yet used any AVX512 instructions, but adds
|
|
// special requirements to check for AVX512 hardware support at runtime (e.g.
|
|
// via sysctl call or commpage inspection). See issue 43089 and link below for
|
|
// full background:
|
|
// https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.1.10/osfmk/i386/fpu.c#L214-L240
|
|
//
|
|
// Additionally, all versions of the Darwin kernel from 19.6.0 through 21.2.0
|
|
// (corresponding to MacOS 10.15.6 - 12.1) have a bug that can cause corruption
|
|
// of the AVX512 mask registers (K0-K7) upon signal return. For this reason
|
|
// AVX512 is considered unsafe to use on Darwin for kernel versions prior to
|
|
// 21.3.0, where a fix has been confirmed. See issue 49233 for full background.
|
|
func darwinSupportsAVX512() bool {
|
|
return darwinSysctlEnabled([]byte("hw.optional.avx512f\x00")) && darwinKernelVersionCheck(21, 3, 0)
|
|
}
|
|
|
|
// Ensure Darwin kernel version is at least major.minor.patch, avoiding dependencies
|
|
func darwinKernelVersionCheck(major, minor, patch int) bool {
|
|
var release [256]byte
|
|
err := darwinOSRelease(&release)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
var mmp [3]int
|
|
c := 0
|
|
Loop:
|
|
for _, b := range release[:] {
|
|
switch {
|
|
case b >= '0' && b <= '9':
|
|
mmp[c] = 10*mmp[c] + int(b-'0')
|
|
case b == '.':
|
|
c++
|
|
if c > 2 {
|
|
return false
|
|
}
|
|
case b == 0:
|
|
break Loop
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
if c != 2 {
|
|
return false
|
|
}
|
|
return mmp[0] > major || mmp[0] == major && (mmp[1] > minor || mmp[1] == minor && mmp[2] >= patch)
|
|
}
|