]> Cypherpunks repositories - gostls13.git/commitdiff
internal/runtime: fix assembly for spectre retpoline instrumentation
authorMichael Anthony Knyszek <mknyszek@google.com>
Tue, 3 Feb 2026 15:45:21 +0000 (15:45 +0000)
committerMichael Knyszek <mknyszek@google.com>
Tue, 3 Feb 2026 19:56:29 +0000 (11:56 -0800)
In the last year we added two CALLs whose targets are loaded from
memory. Change them to call from a register so that the instrumentation
for spectre mitigations works.

This change also adds a smoke test for the spectre build flags.

For #77420.

Change-Id: I35ec723449ff6a712bcce3276bf1df3fa932bddc
Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest
Reviewed-on: https://go-review.googlesource.com/c/go/+/741541
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
src/cmd/dist/test.go
src/internal/runtime/gc/scan/scan_amd64.s
src/internal/runtime/startlinetest/func_amd64.s

index 48c3aa5efdb008b17a68043c6b7caaadb633d966..4984f930b932c0ef82fdd8ad32e703b1d3328d5e 100644 (file)
@@ -789,7 +789,7 @@ func (t *tester) registerTests() {
        if !t.compileOnly && !t.short {
                t.registerTest("GODEBUG=gcstoptheworld=2 archive/zip",
                        &goTest{
-                               variant: "runtime:gcstoptheworld2",
+                               variant: "gcstoptheworld2",
                                timeout: 300 * time.Second,
                                short:   true,
                                env:     []string{"GODEBUG=gcstoptheworld=2"},
@@ -797,7 +797,7 @@ func (t *tester) registerTests() {
                        })
                t.registerTest("GODEBUG=gccheckmark=1 runtime",
                        &goTest{
-                               variant: "runtime:gccheckmark",
+                               variant: "gccheckmark",
                                timeout: 300 * time.Second,
                                short:   true,
                                env:     []string{"GODEBUG=gccheckmark=1"},
@@ -805,6 +805,22 @@ func (t *tester) registerTests() {
                        })
        }
 
+       // Spectre mitigation smoke test.
+       if goos == "linux" && goarch == "amd64" {
+               // Pick a bunch of packages known to have some assembly.
+               pkgs := []string{"internal/runtime/...", "reflect", "crypto/..."}
+               if !t.short {
+                       pkgs = append(pkgs, "runtime")
+               }
+               t.registerTest("spectre",
+                       &goTest{
+                               variant: "spectre",
+                               short:   true,
+                               env:     []string{"GOFLAGS=-gcflags=all=-spectre=all -asmflags=all=-spectre=all"},
+                               pkgs:    pkgs,
+                       })
+       }
+
        // morestack tests. We only run these in long-test mode
        // (with GO_TEST_SHORT=0) because the runtime test is
        // already quite long and mayMoreStackMove makes it about
index 9b4950a7676985d0650cab2df46317071142d9a6..24354a3a1c461de0dd576b1e94c3607a0ae6a2dd 100644 (file)
@@ -12,7 +12,8 @@ TEXT ·ExpandAVX512(SB), NOSPLIT, $0-24
 
        // Call the expander for this size class
        LEAQ ·gcExpandersAVX512(SB), BX
-       CALL (BX)(CX*8)
+       MOVQ (BX)(CX*8), DX // Move to register first so -spectre works
+       CALL DX
 
        MOVQ unpacked+16(FP), DI // Expanded output bitmap pointer
        VMOVDQU64 Z1, 0(DI)
@@ -25,7 +26,8 @@ TEXT ·scanSpanPackedAVX512(SB), NOSPLIT, $256-44
        MOVQ objMarks+16(FP), AX
        MOVQ sizeClass+24(FP), CX
        LEAQ ·gcExpandersAVX512(SB), BX
-       CALL (BX)(CX*8)
+       MOVQ (BX)(CX*8), DX // Move to register first so -spectre works
+       CALL DX
 
        // Z3+Z4 = Load the pointer mask
        MOVQ ptrMask+32(FP), AX
index 96982bedab82c502d3a6e846238bb2d0e1926094..e60ba7af3fc4382cf880075a7e5fb2938dc7a1ed 100644 (file)
@@ -24,5 +24,6 @@ TEXT  ·AsmFunc<ABIInternal>(SB),NOSPLIT,$8-0
        NO_LOCAL_POINTERS
        MOVQ    $0, AX // wantInlined
        MOVQ    ·CallerStartLine(SB), DX
-       CALL    (DX)
+       MOVQ    (DX), DX // Move to a register first for -spectre
+       CALL    DX
        RET