internal/runtime: fix assembly for spectre retpoline instrumentation

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>
This commit is contained in:
Michael Anthony Knyszek 2026-02-03 15:45:21 +00:00 committed by Michael Knyszek
parent e0414d74fe
commit 8572b1cfea
3 changed files with 24 additions and 5 deletions

20
src/cmd/dist/test.go vendored
View 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

View 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

View 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