MOVQ BX, savedm-8(SP) // saved copy of oldm
JMP havem
needm:
- MOVQ $runtime·needm(SB), AX
+ // On some platforms (Windows) we cannot call needm through
+ // an ABI wrapper because there's no TLS set up, and the ABI
+ // wrapper will try to restore the G register (R14) from TLS.
+ // Clear X15 because Go expects it and we're not calling
+ // through a wrapper, but otherwise avoid setting the G
+ // register in the wrapper and call needm directly. It
+ // takes no arguments and doesn't return any values so
+ // there's no need to handle that. Clear R14 so that there's
+ // a bad value in there, in case needm tries to use it.
+ XORPS X15, X15
+ XORQ R14, R14
+ MOVQ $runtime·needm<ABIInternal>(SB), AX
CALL AX
MOVQ $0, savedm-8(SP) // dropm on return
get_tls(CX)
// for the duration of the call. Since the call is over, return it with dropm.
MOVQ savedm-8(SP), BX
CMPQ BX, $0
- JNE 3(PC)
+ JNE done
MOVQ $runtime·dropm(SB), AX
CALL AX
+#ifdef GOOS_windows
+ // We need to clear the TLS pointer in case the next
+ // thread that comes into Go tries to reuse that space
+ // but uses the same M.
+ XORQ DI, DI
+ CALL runtime·settls(SB)
+#endif
+done:
// Done!
RET
// set g. for use by needm.
TEXT runtime·setg(SB), NOSPLIT, $0-8
MOVQ gg+0(FP), BX
-#ifdef GOOS_windows
- CMPQ BX, $0
- JNE settls
- MOVQ $0, 0x28(GS)
- RET
-settls:
- MOVQ g_m(BX), AX
- LEAQ m_tls(AX), AX
- MOVQ AX, 0x28(GS)
-#endif
get_tls(CX)
MOVQ BX, g(CX)
RET
// Store the original signal mask for use by minit.
mp.sigmask = sigmask
+ // Install TLS on some platforms (previously setg
+ // would do this if necessary).
+ osSetupTLS(mp)
+
// 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
--- /dev/null
+// Copyright 2021 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 (windows && !amd64) || !windows
+// +build windows,!amd64 !windows
+
+package runtime
+
+//go:nosplit
+func osSetupTLS(mp *m) {}
--- /dev/null
+// Copyright 2021 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.
+
+package runtime
+
+// osSetupTLS is called by needm to set up TLS for non-Go threads.
+//
+// Defined in assembly.
+func osSetupTLS(mp *m)