]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: don't save G during VDSO if we're handling signal
authorCherry Zhang <cherryyz@google.com>
Sun, 10 Nov 2019 18:18:06 +0000 (13:18 -0500)
committerCherry Zhang <cherryyz@google.com>
Mon, 11 Nov 2019 15:16:05 +0000 (15:16 +0000)
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>
src/runtime/sys_linux_arm.s
src/runtime/sys_linux_arm64.s

index b8dc202d4c9dac1ac41a6dbd84692e04be60557e..8908b1bf23d38a2e42a4aadea5d71ea2233cea4b 100644 (file)
@@ -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)
 
index ddfb13d7a1816178a6ebcfa70a1f7dc2c2e95b6f..8a0f06f206b5a5a18e4bdd060d491642b63003a7 100644 (file)
@@ -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)