Skip to content

Commit b3217a8

Browse files
committed
runtime: Save G on signal stack for PPC VDSO call
1 parent cfbdc1e commit b3217a8

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

src/runtime/sys_linux_ppc64x.s

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -216,29 +216,58 @@ TEXT runtime·walltime(SB),NOSPLIT,$16-12
216216
MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack
217217

218218
noswitch:
219-
SUB $16, R1 // Space for results
220-
RLDICR $0, R1, $59, R1 // Align for C code
221-
MOVD R12, CTR
222-
MOVD R1, R4
223-
BL (CTR) // Call from VDSO
224-
MOVD $0, R0 // Restore R0
225-
MOVD 0(R1), R3 // sec
226-
MOVD 8(R1), R5 // nsec
227-
MOVD R15, R1 // Restore SP
219+
SUB $16, R1 // Space for results
220+
RLDICR $0, R1, $59, R1 // Align for C code
221+
MOVD R12, CTR
222+
MOVD R1, R4
223+
224+
// Store g on gsignal's stack, so if we receive a signal
225+
// during VDSO code we can find the g.
226+
// If we don't have a signal stack, we won't receive signal,
227+
// so don't bother saving g.
228+
// When using cgo, we already saved g on TLS, also don't save
229+
// g here.
230+
// Also don't save g if we are already on the signal stack.
231+
// We won't get a nested signal.
232+
MOVBZ runtime·iscgo(SB), R22
233+
CMP R22, $0
234+
BNE nosaveg
235+
MOVD m_gsignal(R21), R22 // g.m.gsignal
236+
CMP R22, $0
237+
BEQ nosaveg
238+
239+
CMP g, R22
240+
BEQ nosaveg
241+
MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
242+
MOVD g, (R22)
243+
244+
BL (CTR) // Call from VDSO
245+
246+
MOVD $0, (R22) // clear g slot, R22 is unchanged by C code
247+
248+
BL finish
249+
250+
nosaveg:
251+
BL (CTR) // Call from VDSO
252+
253+
finish:
254+
MOVD $0, R0 // Restore R0
255+
MOVD 0(R1), R3 // sec
256+
MOVD 8(R1), R5 // nsec
257+
MOVD R15, R1 // Restore SP
228258

229259
// Restore vdsoPC, vdsoSP
230260
// We don't worry about being signaled between the two stores.
231261
// If we are not in a signal handler, we'll restore vdsoSP to 0,
232262
// and no one will care about vdsoPC. If we are in a signal handler,
233263
// we cannot receive another signal.
234-
MOVD 40(R1), R6
235-
MOVD R6, m_vdsoSP(R21)
236-
MOVD 32(R1), R6
237-
MOVD R6, m_vdsoPC(R21)
264+
MOVD 40(R1), R6
265+
MOVD R6, m_vdsoSP(R21)
266+
MOVD 32(R1), R6
267+
MOVD R6, m_vdsoPC(R21)
238268

239-
finish:
240-
MOVD R3, sec+0(FP)
241-
MOVW R5, nsec+8(FP)
269+
MOVD R3, sec+0(FP)
270+
MOVW R5, nsec+8(FP)
242271
RET
243272

244273
// Syscall fallback
@@ -469,7 +498,7 @@ TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0
469498
// this might be called in external code context,
470499
// where g is not set.
471500
MOVBZ runtime·iscgo(SB), R6
472-
CMP R6, $0
501+
CMP R6, $0
473502
BEQ 2(PC)
474503
BL runtime·load_g(SB)
475504

0 commit comments

Comments
 (0)