runtime: enable async preemption on darwin/arm64

The problem should be fixed by the previous CL. Reenable async
preemption on darwin/arm64.

Updates #35439.

Change-Id: I93e8c4702b4d8fe6abaa6fc9c27def5c8aed1b59
Reviewed-on: https://go-review.googlesource.com/c/go/+/206419
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
index 987740c..615ec18 100644
--- a/src/runtime/mkpreempt.go
+++ b/src/runtime/mkpreempt.go
@@ -342,6 +342,12 @@
 	p("MOVD R29, -8(RSP)") // save frame pointer (only used on Linux)
 	p("SUB $8, RSP, R29")  // set up new frame pointer
 	p("#endif")
+	// On darwin, save the LR again after decrementing SP. We run the
+	// signal handler on the G stack (as it doesn't support SA_ONSTACK),
+	// so any writes below SP may be clobbered.
+	p("#ifdef GOOS_darwin")
+	p("MOVD R30, (RSP)")
+	p("#endif")
 
 	l.save()
 	p("CALL ·asyncPreempt2(SB)")
diff --git a/src/runtime/preempt_arm64.s b/src/runtime/preempt_arm64.s
index 3a7cdf4..3c27b52 100644
--- a/src/runtime/preempt_arm64.s
+++ b/src/runtime/preempt_arm64.s
@@ -10,6 +10,9 @@
 	MOVD R29, -8(RSP)
 	SUB $8, RSP, R29
 	#endif
+	#ifdef GOOS_darwin
+	MOVD R30, (RSP)
+	#endif
 	MOVD R0, 8(RSP)
 	MOVD R1, 16(RSP)
 	MOVD R2, 24(RSP)
diff --git a/src/runtime/signal_arm64.go b/src/runtime/signal_arm64.go
index fb09aff..db2ab27 100644
--- a/src/runtime/signal_arm64.go
+++ b/src/runtime/signal_arm64.go
@@ -79,9 +79,7 @@
 	c.set_pc(uint64(funcPC(sigpanic)))
 }
 
-// TODO(issue 35439): enabling async preemption causes failures on darwin/arm64.
-// Disable for now.
-const pushCallSupported = GOOS != "darwin"
+const pushCallSupported = true
 
 func (c *sigctxt) pushCall(targetPC uintptr) {
 	// Push the LR to stack, as we'll clobber it in order to