Skip to content

Commit 75c839a

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent c31bcd1 commit 75c839a

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

src/runtime/sys_linux_arm.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,16 @@ noswitch:
279279
// so don't bother saving g.
280280
// When using cgo, we already saved g on TLS, also don't save
281281
// g here.
282+
// Also don't save g if we are already on the signal stack.
283+
// We won't get a nested signal.
282284
MOVB runtime·iscgo(SB), R6
283285
CMP $0, R6
284286
BNE nosaveg
285287
MOVW m_gsignal(R5), R6 // g.m.gsignal
286288
CMP $0, R6
287289
BEQ nosaveg
290+
CMP g, R6
291+
BEQ nosaveg
288292
MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
289293
MOVW g, (R6)
290294

@@ -353,12 +357,16 @@ noswitch:
353357
// so don't bother saving g.
354358
// When using cgo, we already saved g on TLS, also don't save
355359
// g here.
360+
// Also don't save g if we are already on the signal stack.
361+
// We won't get a nested signal.
356362
MOVB runtime·iscgo(SB), R6
357363
CMP $0, R6
358364
BNE nosaveg
359365
MOVW m_gsignal(R5), R6 // g.m.gsignal
360366
CMP $0, R6
361367
BEQ nosaveg
368+
CMP g, R6
369+
BEQ nosaveg
362370
MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
363371
MOVW g, (R6)
364372

src/runtime/sys_linux_arm64.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,14 @@ noswitch:
239239
// so don't bother saving g.
240240
// When using cgo, we already saved g on TLS, also don't save
241241
// g here.
242+
// Also don't save g if we are already on the signal stack.
243+
// We won't get a nested signal.
242244
MOVBU runtime·iscgo(SB), R22
243245
CBNZ R22, nosaveg
244246
MOVD m_gsignal(R21), R22 // g.m.gsignal
245247
CBZ R22, nosaveg
248+
CMP g, R22
249+
BEQ nosaveg
246250
MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
247251
MOVD g, (R22)
248252

@@ -303,10 +307,14 @@ noswitch:
303307
// so don't bother saving g.
304308
// When using cgo, we already saved g on TLS, also don't save
305309
// g here.
310+
// Also don't save g if we are already on the signal stack.
311+
// We won't get a nested signal.
306312
MOVBU runtime·iscgo(SB), R22
307313
CBNZ R22, nosaveg
308314
MOVD m_gsignal(R21), R22 // g.m.gsignal
309315
CBZ R22, nosaveg
316+
CMP g, R22
317+
BEQ nosaveg
310318
MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
311319
MOVD g, (R22)
312320

0 commit comments

Comments
 (0)