]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: save/fetch g register during VDSO on linux/loong64
authorGuoqi Chen <chenguoqi@loongson.cn>
Tue, 28 Mar 2023 21:10:45 +0000 (05:10 +0800)
committerGopher Robot <gobot@golang.org>
Thu, 11 May 2023 23:41:03 +0000 (23:41 +0000)
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 <git@xen0n.name>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Run-TryBot: WANG Xuerui <git@xen0n.name>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/runtime/signal_unix.go
src/runtime/sys_linux_loong64.s

index 5f733a90da8fdd57ce071a31c63aa4dba0167156..8a745ecda08836f50f162d5534bf3a0ed9287427 100644 (file)
@@ -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.
index 486a9b1570d2ddd740832b80251f4379acef454a..12e5455345e8e474e90e3c1dede78893c7f25336 100644 (file)
@@ -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: