aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/runtime/os1_darwin.go17
-rw-r--r--src/runtime/os1_dragonfly.go16
-rw-r--r--src/runtime/os1_freebsd.go17
-rw-r--r--src/runtime/os1_linux.go17
-rw-r--r--src/runtime/os1_nacl.go9
-rw-r--r--src/runtime/os1_netbsd.go18
-rw-r--r--src/runtime/os1_openbsd.go17
-rw-r--r--src/runtime/os1_plan9.go6
-rw-r--r--src/runtime/os1_windows.go10
-rw-r--r--src/runtime/os3_solaris.go18
-rw-r--r--src/runtime/proc1.go22
11 files changed, 140 insertions, 27 deletions
diff --git a/src/runtime/os1_darwin.go b/src/runtime/os1_darwin.go
index e07022997c..c9dba152ab 100644
--- a/src/runtime/os1_darwin.go
+++ b/src/runtime/os1_darwin.go
@@ -130,6 +130,7 @@ func mpreinit(mp *m) {
mp.gsignal.m = mp
}
+//go:nosplit
func msigsave(mp *m) {
smask := (*uint32)(unsafe.Pointer(&mp.sigmask))
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
@@ -138,6 +139,17 @@ func msigsave(mp *m) {
sigprocmask(_SIG_SETMASK, nil, smask)
}
+//go:nosplit
+func msigrestore(mp *m) {
+ smask := (*uint32)(unsafe.Pointer(&mp.sigmask))
+ sigprocmask(_SIG_SETMASK, smask, nil)
+}
+
+//go:nosplit
+func sigblock() {
+ sigprocmask(_SIG_SETMASK, &sigset_all, nil)
+}
+
// Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory.
func minit() {
@@ -156,10 +168,8 @@ func minit() {
}
// Called from dropm to undo the effect of an minit.
+//go:nosplit
func unminit() {
- _g_ := getg()
- smask := (*uint32)(unsafe.Pointer(&_g_.m.sigmask))
- sigprocmask(_SIG_SETMASK, smask, nil)
signalstack(nil)
}
@@ -459,6 +469,7 @@ func getsig(i int32) uintptr {
return *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u))
}
+//go:nosplit
func signalstack(s *stack) {
var st stackt
if s == nil {
diff --git a/src/runtime/os1_dragonfly.go b/src/runtime/os1_dragonfly.go
index f96c78ca80..da70014e55 100644
--- a/src/runtime/os1_dragonfly.go
+++ b/src/runtime/os1_dragonfly.go
@@ -119,6 +119,7 @@ func mpreinit(mp *m) {
mp.gsignal.m = mp
}
+//go:nosplit
func msigsave(mp *m) {
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
@@ -127,6 +128,17 @@ func msigsave(mp *m) {
sigprocmask(_SIG_SETMASK, nil, smask)
}
+//go:nosplit
+func msigrestore(mp *m) {
+ smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
+ sigprocmask(_SIG_SETMASK, smask, nil)
+}
+
+//go:nosplit
+func sigblock() {
+ sigprocmask(_SIG_SETMASK, &sigset_all, nil)
+}
+
// Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory.
func minit() {
@@ -150,9 +162,6 @@ func minit() {
// Called from dropm to undo the effect of an minit.
func unminit() {
- _g_ := getg()
- smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
- sigprocmask(_SIG_SETMASK, smask, nil)
signalstack(nil)
}
@@ -222,6 +231,7 @@ func getsig(i int32) uintptr {
return sa.sa_sigaction
}
+//go:nosplit
func signalstack(s *stack) {
var st sigaltstackt
if s == nil {
diff --git a/src/runtime/os1_freebsd.go b/src/runtime/os1_freebsd.go
index f3519f3490..b18e60f9b6 100644
--- a/src/runtime/os1_freebsd.go
+++ b/src/runtime/os1_freebsd.go
@@ -118,6 +118,7 @@ func mpreinit(mp *m) {
mp.gsignal.m = mp
}
+//go:nosplit
func msigsave(mp *m) {
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
@@ -126,6 +127,17 @@ func msigsave(mp *m) {
sigprocmask(_SIG_SETMASK, nil, smask)
}
+//go:nosplit
+func msigrestore(mp *m) {
+ smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
+ sigprocmask(_SIG_SETMASK, smask, nil)
+}
+
+//go:nosplit
+func sigblock() {
+ sigprocmask(_SIG_SETMASK, &sigset_all, nil)
+}
+
// Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory.
func minit() {
@@ -151,10 +163,8 @@ func minit() {
}
// Called from dropm to undo the effect of an minit.
+//go:nosplit
func unminit() {
- _g_ := getg()
- smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
- sigprocmask(_SIG_SETMASK, smask, nil)
signalstack(nil)
}
@@ -224,6 +234,7 @@ func getsig(i int32) uintptr {
return sa.sa_handler
}
+//go:nosplit
func signalstack(s *stack) {
var st stackt
if s == nil {
diff --git a/src/runtime/os1_linux.go b/src/runtime/os1_linux.go
index 1cad8f776a..166014b502 100644
--- a/src/runtime/os1_linux.go
+++ b/src/runtime/os1_linux.go
@@ -198,6 +198,7 @@ func mpreinit(mp *m) {
mp.gsignal.m = mp
}
+//go:nosplit
func msigsave(mp *m) {
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
@@ -206,6 +207,17 @@ func msigsave(mp *m) {
rtsigprocmask(_SIG_SETMASK, nil, smask, int32(unsafe.Sizeof(*smask)))
}
+//go:nosplit
+func msigrestore(mp *m) {
+ smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
+ rtsigprocmask(_SIG_SETMASK, smask, nil, int32(unsafe.Sizeof(*smask)))
+}
+
+//go:nosplit
+func sigblock() {
+ rtsigprocmask(_SIG_SETMASK, &sigset_all, nil, int32(unsafe.Sizeof(sigset_all)))
+}
+
func gettid() uint32
// Called to initialize a new m (including the bootstrap m).
@@ -229,10 +241,8 @@ func minit() {
}
// Called from dropm to undo the effect of an minit.
+//go:nosplit
func unminit() {
- _g_ := getg()
- smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
- rtsigprocmask(_SIG_SETMASK, smask, nil, int32(unsafe.Sizeof(*smask)))
signalstack(nil)
}
@@ -326,6 +336,7 @@ func getsig(i int32) uintptr {
return sa.sa_handler
}
+//go:nosplit
func signalstack(s *stack) {
var st sigaltstackt
if s == nil {
diff --git a/src/runtime/os1_nacl.go b/src/runtime/os1_nacl.go
index 143752ada8..30c352968a 100644
--- a/src/runtime/os1_nacl.go
+++ b/src/runtime/os1_nacl.go
@@ -15,9 +15,18 @@ func mpreinit(mp *m) {
func sigtramp()
+//go:nosplit
func msigsave(mp *m) {
}
+//go:nosplit
+func msigrestore(mp *m) {
+}
+
+//go:nosplit
+func sigblock() {
+}
+
// Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory.
func minit() {
diff --git a/src/runtime/os1_netbsd.go b/src/runtime/os1_netbsd.go
index cacd60620b..f4c5ca48eb 100644
--- a/src/runtime/os1_netbsd.go
+++ b/src/runtime/os1_netbsd.go
@@ -138,6 +138,7 @@ func mpreinit(mp *m) {
mp.gsignal.m = mp
}
+//go:nosplit
func msigsave(mp *m) {
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
@@ -146,6 +147,17 @@ func msigsave(mp *m) {
sigprocmask(_SIG_SETMASK, nil, smask)
}
+//go:nosplit
+func msigrestore(mp *m) {
+ smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
+ sigprocmask(_SIG_SETMASK, smask, nil)
+}
+
+//go:nosplit
+func sigblock() {
+ sigprocmask(_SIG_SETMASK, &sigset_all, nil)
+}
+
// Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory.
func minit() {
@@ -166,11 +178,8 @@ func minit() {
}
// Called from dropm to undo the effect of an minit.
+//go:nosplit
func unminit() {
- _g_ := getg()
- smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
- sigprocmask(_SIG_SETMASK, smask, nil)
-
signalstack(nil)
}
@@ -213,6 +222,7 @@ func getsig(i int32) uintptr {
return sa.sa_sigaction
}
+//go:nosplit
func signalstack(s *stack) {
var st sigaltstackt
if s == nil {
diff --git a/src/runtime/os1_openbsd.go b/src/runtime/os1_openbsd.go
index 24a095b9d6..88f6aef3e2 100644
--- a/src/runtime/os1_openbsd.go
+++ b/src/runtime/os1_openbsd.go
@@ -148,6 +148,7 @@ func mpreinit(mp *m) {
mp.gsignal.m = mp
}
+//go:nosplit
func msigsave(mp *m) {
smask := (*uint32)(unsafe.Pointer(&mp.sigmask))
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
@@ -156,6 +157,17 @@ func msigsave(mp *m) {
*smask = sigprocmask(_SIG_BLOCK, 0)
}
+//go:nosplit
+func msigrestore(mp *m) {
+ smask := *(*uint32)(unsafe.Pointer(&mp.sigmask))
+ sigprocmask(_SIG_SETMASK, smask)
+}
+
+//go:nosplit
+func sigblock() {
+ sigprocmask(_SIG_SETMASK, sigset_all)
+}
+
// Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory.
func minit() {
@@ -178,10 +190,8 @@ func minit() {
}
// Called from dropm to undo the effect of an minit.
+//go:nosplit
func unminit() {
- _g_ := getg()
- smask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask))
- sigprocmask(_SIG_SETMASK, smask)
signalstack(nil)
}
@@ -224,6 +234,7 @@ func getsig(i int32) uintptr {
return sa.sa_sigaction
}
+//go:nosplit
func signalstack(s *stack) {
var st stackt
if s == nil {
diff --git a/src/runtime/os1_plan9.go b/src/runtime/os1_plan9.go
index 9615b6d1a4..38125a01f8 100644
--- a/src/runtime/os1_plan9.go
+++ b/src/runtime/os1_plan9.go
@@ -21,6 +21,12 @@ func mpreinit(mp *m) {
func msigsave(mp *m) {
}
+func msigrestore(mp *m) {
+}
+
+func sigblock() {
+}
+
// Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory.
func minit() {
diff --git a/src/runtime/os1_windows.go b/src/runtime/os1_windows.go
index f608b4ad80..d0120347db 100644
--- a/src/runtime/os1_windows.go
+++ b/src/runtime/os1_windows.go
@@ -284,9 +284,18 @@ func newosproc(mp *m, stk unsafe.Pointer) {
func mpreinit(mp *m) {
}
+//go:nosplit
func msigsave(mp *m) {
}
+//go:nosplit
+func msigrestore(mp *m) {
+}
+
+//go:nosplit
+func sigblock() {
+}
+
// Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory.
func minit() {
@@ -296,6 +305,7 @@ func minit() {
}
// Called from dropm to undo the effect of an minit.
+//go:nosplit
func unminit() {
tp := &getg().m.thread
stdcall1(_CloseHandle, *tp)
diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go
index 792188fea6..b27a675159 100644
--- a/src/runtime/os3_solaris.go
+++ b/src/runtime/os3_solaris.go
@@ -192,6 +192,7 @@ func mpreinit(mp *m) {
func miniterrno()
+//go:nosplit
func msigsave(mp *m) {
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
@@ -200,6 +201,17 @@ func msigsave(mp *m) {
sigprocmask(_SIG_SETMASK, nil, smask)
}
+//go:nosplit
+func msigrestore(mp *m) {
+ smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
+ sigprocmask(_SIG_SETMASK, smask, nil)
+}
+
+//go:nosplit
+func sigblock() {
+ sigprocmask(_SIG_SETMASK, &sigset_all, nil)
+}
+
// Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory.
func minit() {
@@ -220,10 +232,6 @@ func minit() {
// Called from dropm to undo the effect of an minit.
func unminit() {
- _g_ := getg()
- smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
- sigprocmask(_SIG_SETMASK, smask, nil)
-
signalstack(nil)
}
@@ -289,6 +297,7 @@ func getsig(i int32) uintptr {
return *((*uintptr)(unsafe.Pointer(&sa._funcptr)))
}
+//go:nosplit
func signalstack(s *stack) {
var st sigaltstackt
if s == nil {
@@ -493,6 +502,7 @@ func sigaltstack(ss *sigaltstackt, oss *sigaltstackt) /* int32 */ {
sysvicall2(&libc_sigaltstack, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(oss)))
}
+//go:nosplit
func sigprocmask(how int32, set *sigset, oset *sigset) /* int32 */ {
sysvicall3(&libc_sigprocmask, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oset)))
}
diff --git a/src/runtime/proc1.go b/src/runtime/proc1.go
index 54cb3eb77f..72ab524bd2 100644
--- a/src/runtime/proc1.go
+++ b/src/runtime/proc1.go
@@ -945,6 +945,15 @@ func needm(x byte) {
mp.needextram = mp.schedlink == 0
unlockextra(mp.schedlink.ptr())
+ // Save and block signals before installing g.
+ // Once g is installed, any incoming signals will try to execute,
+ // but we won't have the sigaltstack settings and other data
+ // set up appropriately until the end of minit, which will
+ // unblock the signals. This is the same dance as when
+ // starting a new m to run Go code via newosproc.
+ msigsave(mp)
+ sigblock()
+
// Install g (= m->g0) and set the stack bounds
// to match the current stack. We don't actually know
// how big the stack is, like we don't know how big any
@@ -956,7 +965,6 @@ func needm(x byte) {
_g_.stack.lo = uintptr(noescape(unsafe.Pointer(&x))) - 32*1024
_g_.stackguard0 = _g_.stack.lo + _StackGuard
- msigsave(mp)
// Initialize this thread to use the m.
asminit()
minit()
@@ -1027,9 +1035,6 @@ func newextram() {
// We may have to keep the current version on systems with cgo
// but without pthreads, like Windows.
func dropm() {
- // Undo whatever initialization minit did during needm.
- unminit()
-
// Clear m and g, and return m to the extra list.
// After the call to setg we can only call nosplit functions
// with no pointer manipulation.
@@ -1037,7 +1042,16 @@ func dropm() {
mnext := lockextra(true)
mp.schedlink.set(mnext)
+ // Block signals before unminit.
+ // Unminit unregisters the signal handling stack (but needs g on some systems).
+ // Setg(nil) clears g, which is the signal handler's cue not to run Go handlers.
+ // It's important not to try to handle a signal between those two steps.
+ sigblock()
+ unminit()
setg(nil)
+ msigrestore(mp)
+
+ // Commit the release of mp.
unlockextra(mp)
}