From f07cbc7f88e5e15e41ec8b9c2b850d2179e0834e Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Thu, 31 Oct 2019 10:32:31 -0400 Subject: runtime: don't fetch G from signal stack when using cgo When using cgo, we save G to TLS, and when a signal happens, we load G from TLS in sigtramp. This should give us a valid G. Don't try to fetch from the signal stack. In particular, C code may change the signal stack or call our signal handler directly (e.g. TSAN), so we are not necessarily running on the original gsignal stack where we saved G. Also skip saving G on the signal stack when using cgo. Updates #35249. Change-Id: I40749ce6682709bd4ebfdfd9f23bd0f317fc197d Reviewed-on: https://go-review.googlesource.com/c/go/+/204519 Reviewed-by: Ian Lance Taylor --- src/runtime/sys_linux_arm64.s | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src/runtime/sys_linux_arm64.s') diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s index e0d681ebf1..ddfb13d7a1 100644 --- a/src/runtime/sys_linux_arm64.s +++ b/src/runtime/sys_linux_arm64.s @@ -237,18 +237,25 @@ noswitch: // during VDSO code we can find the g. // If we don't have a signal stack, we won't receive signal, // so don't bother saving g. + // When using cgo, we already saved g on TLS, also don't save + // g here. + MOVBU runtime·iscgo(SB), R22 + CBNZ R22, nosaveg MOVD m_gsignal(R21), R22 // g.m.gsignal - CBZ R22, 3(PC) + CBZ R22, nosaveg MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo MOVD g, (R22) BL (R2) - CBZ R22, 2(PC) // R22 is unchanged by C code - MOVD ZR, (R22) // clear g slot + MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code B finish +nosaveg: + BL (R2) + B finish + fallback: MOVD $SYS_clock_gettime, R8 SVC @@ -294,18 +301,25 @@ noswitch: // during VDSO code we can find the g. // If we don't have a signal stack, we won't receive signal, // so don't bother saving g. + // When using cgo, we already saved g on TLS, also don't save + // g here. + MOVBU runtime·iscgo(SB), R22 + CBNZ R22, nosaveg MOVD m_gsignal(R21), R22 // g.m.gsignal - CBZ R22, 3(PC) + CBZ R22, nosaveg MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo MOVD g, (R22) BL (R2) - CBZ R22, 2(PC) // R22 is unchanged by C code - MOVD ZR, (R22) // clear g slot + MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code B finish +nosaveg: + BL (R2) + B finish + fallback: MOVD $SYS_clock_gettime, R8 SVC -- cgit v1.3-5-g9baa