Skip to content

Commit 01f99b4

Browse files
committed
cmd/compile: mark DUFFZERO/DUFFCOPY as async unsafe
These operations are async unsafe on architectures that use frame pointers. The reason is they rely on data being safe when stored below the stack pointer. They do: 45da69: 48 89 6c 24 f0 mov %rbp,-0x10(%rsp) 45da6e: 48 8d 6c 24 f0 lea -0x10(%rsp),%rbp 45da73: e8 7d d0 ff ff callq 45aaf5 <runtime.duffzero+0x115> 45da78: 48 8b 6d 00 mov 0x0(%rbp),%rbp This dance ensures that inside duffzero, it looks like there is a proper frame pointer set up, so that stack walkbacks work correctly if the kernel samples during duffzero. However, this instruction sequence depends on data not being clobbered even though it is below the stack pointer. If there is an async interrupt at any of those last 3 instructions, and the interrupt decides to insert a call to asyncPreempt, then the saved frame pointer on the stack gets clobbered. The last instruction above then restores junk to the frame pointer. To prevent this, mark these instructions as async unsafe. (The body of duffzero is already async unsafe, as it is in package runtime.) Change-Id: I5562e82f9f5bd2fb543dcf2b6b9133d87ff83032 Reviewed-on: https://go-review.googlesource.com/c/go/+/248261 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Martin Möhrmann <[email protected]> Reviewed-by: Cherry Zhang <[email protected]>
1 parent c6a11f0 commit 01f99b4

File tree

3 files changed

+8
-0
lines changed

3 files changed

+8
-0
lines changed

src/cmd/compile/internal/ssa/gen/AMD64Ops.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,7 @@ func init() {
748748
clobbers: buildReg("DI"),
749749
},
750750
faultOnNilArg0: true,
751+
unsafePoint: true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
751752
},
752753
{name: "MOVOconst", reg: regInfo{nil, 0, []regMask{fp}}, typ: "Int128", aux: "Int128", rematerializeable: true},
753754

@@ -786,6 +787,7 @@ func init() {
786787
clobberFlags: true,
787788
faultOnNilArg0: true,
788789
faultOnNilArg1: true,
790+
unsafePoint: true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
789791
},
790792

791793
// arg0 = destination pointer

src/cmd/compile/internal/ssa/gen/ARM64Ops.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ func init() {
507507
clobbers: buildReg("R20 R30"),
508508
},
509509
faultOnNilArg0: true,
510+
unsafePoint: true, // FP maintenance around DUFFZERO can be clobbered by interrupts
510511
},
511512

512513
// large zeroing
@@ -547,6 +548,7 @@ func init() {
547548
},
548549
faultOnNilArg0: true,
549550
faultOnNilArg1: true,
551+
unsafePoint: true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
550552
},
551553

552554
// large move

src/cmd/compile/internal/ssa/opGen.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)