mirror of https://github.com/golang/go.git
75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
// Copyright 2019 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.
|
|
|
|
// +build linux
|
|
// +build 386 amd64
|
|
|
|
package runtime
|
|
|
|
//go:noescape
|
|
func uname(utsname *new_utsname) int
|
|
|
|
func mlock(addr, len uintptr) int
|
|
|
|
func osArchInit() {
|
|
// Linux 5.2 introduced a bug that can corrupt vector
|
|
// registers on return from a signal if the signal stack isn't
|
|
// faulted in:
|
|
// https://bugzilla.kernel.org/show_bug.cgi?id=205663
|
|
//
|
|
// It was fixed in 5.3.15, 5.4.2, and all 5.5 and later
|
|
// kernels.
|
|
//
|
|
// If we're on an affected kernel, work around this issue by
|
|
// mlocking the top page of every signal stack. This doesn't
|
|
// help for signal stacks created in C, but there's not much
|
|
// we can do about that.
|
|
//
|
|
// TODO(austin): Remove this in Go 1.15, at which point it
|
|
// will be unlikely to encounter any of the affected kernels
|
|
// in the wild.
|
|
|
|
var uts new_utsname
|
|
if uname(&uts) < 0 {
|
|
throw("uname failed")
|
|
}
|
|
// Check for null terminator to ensure gostringnocopy doesn't
|
|
// walk off the end of the release string.
|
|
found := false
|
|
for _, b := range uts.release {
|
|
if b == 0 {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
return
|
|
}
|
|
rel := gostringnocopy(&uts.release[0])
|
|
|
|
major, minor, patch, ok := parseRelease(rel)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
if major == 5 && (minor == 2 || minor == 3 && patch < 15 || minor == 4 && patch < 2) {
|
|
gsignalInitQuirk = mlockGsignal
|
|
if m0.gsignal != nil {
|
|
throw("gsignal quirk too late")
|
|
}
|
|
}
|
|
}
|
|
|
|
func mlockGsignal(gsignal *g) {
|
|
if err := mlock(gsignal.stack.hi-physPageSize, physPageSize); err < 0 {
|
|
printlock()
|
|
println("runtime: mlock of signal stack failed:", -err)
|
|
if err == -_ENOMEM {
|
|
println("runtime: increase the mlock limit (ulimit -l) or")
|
|
}
|
|
println("runtime: update your kernel to 5.3.15+, 5.4.2+, or 5.5+")
|
|
throw("mlock failed")
|
|
}
|
|
}
|