From: Guoqi Chen Date: Tue, 28 Mar 2023 21:10:45 +0000 (+0800) Subject: runtime: save/fetch g register during VDSO on linux/loong64 X-Git-Tag: go1.21rc1~570 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=42023d6f529239680773eab5343eedf641e78bb3;p=gostls13.git runtime: save/fetch g register during VDSO on linux/loong64 Like arm64, ppc64 and risv64, on loong64, the G register may be temporarily broken during a VDSO call. If a signal is received during a VDSO call, an invalid G may be obtained. See #34391. Change-Id: Iaffa8cce4f0ef8ef74225c355ec3c20ed238025f Reviewed-on: https://go-review.googlesource.com/c/go/+/426355 Reviewed-by: WANG Xuerui TryBot-Result: Gopher Robot Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor Run-TryBot: WANG Xuerui Auto-Submit: Ian Lance Taylor Reviewed-by: Cherry Mui --- diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go index 5f733a90da..8a745ecda0 100644 --- a/src/runtime/signal_unix.go +++ b/src/runtime/signal_unix.go @@ -397,7 +397,7 @@ func preemptM(mp *m) { //go:nosplit func sigFetchG(c *sigctxt) *g { switch GOARCH { - case "arm", "arm64", "ppc64", "ppc64le", "riscv64", "s390x": + case "arm", "arm64", "loong64", "ppc64", "ppc64le", "riscv64", "s390x": if !iscgo && inVDSOPage(c.sigpc()) { // When using cgo, we save the g on TLS and load it from there // in sigtramp. Just use that. diff --git a/src/runtime/sys_linux_loong64.s b/src/runtime/sys_linux_loong64.s index 486a9b1570..12e5455345 100644 --- a/src/runtime/sys_linux_loong64.s +++ b/src/runtime/sys_linux_loong64.s @@ -11,7 +11,9 @@ #include "textflag.h" #include "cgo/abi_loong64.h" -#define AT_FDCWD -100 +#define AT_FDCWD -100 +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 #define SYS_exit 93 #define SYS_read 63 @@ -233,7 +235,7 @@ TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28 RET // func walltime() (sec int64, nsec int32) -TEXT runtime·walltime(SB),NOSPLIT,$16-12 +TEXT runtime·walltime(SB),NOSPLIT,$24-12 MOVV R3, R23 // R23 is unchanged by C code MOVV R3, R25 @@ -263,12 +265,29 @@ noswitch: AND $~15, R25 // Align for C code MOVV R25, R3 - MOVW $0, R4 // CLOCK_REALTIME=0 + MOVW $CLOCK_REALTIME, R4 MOVV $0(R3), R5 MOVV runtime·vdsoClockgettimeSym(SB), R20 BEQ R20, fallback + // Store g on gsignal's stack, see sys_linux_arm64.s for detail + MOVBU runtime·iscgo(SB), R25 + BNE R25, nosaveg + + MOVV m_gsignal(R24), R25 // g.m.gsignal + BEQ R25, nosaveg + BEQ g, R25, nosaveg + + MOVV (g_stack+stack_lo)(R25), R25 // g.m.gsignal.stack.lo + MOVV g, (R25) + + JAL (R20) + + MOVV R0, (R25) + JMP finish + +nosaveg: JAL (R20) finish: @@ -326,12 +345,29 @@ noswitch: AND $~15, R25 // Align for C code MOVV R25, R3 - MOVW $1, R4 // CLOCK_MONOTONIC=1 + MOVW $CLOCK_MONOTONIC, R4 MOVV $0(R3), R5 MOVV runtime·vdsoClockgettimeSym(SB), R20 BEQ R20, fallback + // Store g on gsignal's stack, see sys_linux_arm64.s for detail + MOVBU runtime·iscgo(SB), R25 + BNE R25, nosaveg + + MOVV m_gsignal(R24), R25 // g.m.gsignal + BEQ R25, nosaveg + BEQ g, R25, nosaveg + + MOVV (g_stack+stack_lo)(R25), R25 // g.m.gsignal.stack.lo + MOVV g, (R25) + + JAL (R20) + + MOVV R0, (R25) + JMP finish + +nosaveg: JAL (R20) finish: