aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sys_linux_arm.s
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-11-10 13:18:06 -0500
committerCherry Zhang <cherryyz@google.com>2019-11-11 15:16:05 +0000
commit75c839af22a50cb027766ea54335e234dac32836 (patch)
tree7fd053338aafb680c696f070f77667f309190079 /src/runtime/sys_linux_arm.s
parentc31bcd13909edb53621c3dc47aa987365247df8d (diff)
downloadgo-75c839af22a50cb027766ea54335e234dac32836.tar.gz
go-75c839af22a50cb027766ea54335e234dac32836.zip
runtime: don't save G during VDSO if we're handling signal
On some platforms (currently ARM and ARM64), when calling into VDSO we store the G to the gsignal stack, if there is one, so if we receive a signal during VDSO we can find the G. If we receive a signal during VDSO, and within the signal handler we call nanotime again (e.g. when handling profiling signal), we'll save/clear the G slot on the gsignal stack again, which clobbers the original saved G. If we receive a second signal during the same VDSO execution, we will fetch a nil G, which will lead to bad things such as deadlock. Don't save G if we're calling VDSO code from the gsignal stack. Saving G is not necessary as we won't receive a nested signal. Fixes #35473. Change-Id: Ibfd8587a3c70c2f1533908b056e81b94d75d65a5 Reviewed-on: https://go-review.googlesource.com/c/go/+/206397 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/runtime/sys_linux_arm.s')
-rw-r--r--src/runtime/sys_linux_arm.s8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s
index b8dc202d4c..8908b1bf23 100644
--- a/src/runtime/sys_linux_arm.s
+++ b/src/runtime/sys_linux_arm.s
@@ -279,12 +279,16 @@ noswitch:
// so don't bother saving g.
// When using cgo, we already saved g on TLS, also don't save
// g here.
+ // Also don't save g if we are already on the signal stack.
+ // We won't get a nested signal.
MOVB runtime·iscgo(SB), R6
CMP $0, R6
BNE nosaveg
MOVW m_gsignal(R5), R6 // g.m.gsignal
CMP $0, R6
BEQ nosaveg
+ CMP g, R6
+ BEQ nosaveg
MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
MOVW g, (R6)
@@ -353,12 +357,16 @@ noswitch:
// so don't bother saving g.
// When using cgo, we already saved g on TLS, also don't save
// g here.
+ // Also don't save g if we are already on the signal stack.
+ // We won't get a nested signal.
MOVB runtime·iscgo(SB), R6
CMP $0, R6
BNE nosaveg
MOVW m_gsignal(R5), R6 // g.m.gsignal
CMP $0, R6
BEQ nosaveg
+ CMP g, R6
+ BEQ nosaveg
MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
MOVW g, (R6)