From: Cherry Zhang Date: Sun, 10 Nov 2019 18:18:06 +0000 (-0500) Subject: runtime: don't save G during VDSO if we're handling signal X-Git-Tag: go1.14beta1~269 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=75c839af22a50cb027766ea54335e234dac32836;p=gostls13.git 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 TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills --- 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) diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s index ddfb13d7a1..8a0f06f206 100644 --- a/src/runtime/sys_linux_arm64.s +++ b/src/runtime/sys_linux_arm64.s @@ -239,10 +239,14 @@ 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. MOVBU runtime·iscgo(SB), R22 CBNZ R22, nosaveg MOVD m_gsignal(R21), R22 // g.m.gsignal CBZ R22, nosaveg + CMP g, R22 + BEQ nosaveg MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo MOVD g, (R22) @@ -303,10 +307,14 @@ 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. MOVBU runtime·iscgo(SB), R22 CBNZ R22, nosaveg MOVD m_gsignal(R21), R22 // g.m.gsignal CBZ R22, nosaveg + CMP g, R22 + BEQ nosaveg MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo MOVD g, (R22)