aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/signal_ppc64x.go
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-10-28 00:53:14 -0400
committerCherry Zhang <cherryyz@google.com>2019-11-08 16:44:48 +0000
commit374c2847f9c03da7365bfb78e5ef96a0cb837656 (patch)
treed53e66576fc42b184a39be7569fe1bacdea70f85 /src/runtime/signal_ppc64x.go
parent7f574e476ac4a6e8c2719b9674ee7b3786bb8401 (diff)
downloadgo-374c2847f9c03da7365bfb78e5ef96a0cb837656.tar.gz
go-374c2847f9c03da7365bfb78e5ef96a0cb837656.zip
runtime: add async preemption support on PPC64
This CL adds support of call injection and async preemption on PPC64. For the injected call to return to the preempted PC, we have to clobber either LR or CTR. For reasons mentioned in previous CLs, we choose CTR. Previous CLs have marked code sequences that use CTR async-nonpreemtible. Change-Id: Ia642b5f06a890dd52476f45023b2a830c522eee0 Reviewed-on: https://go-review.googlesource.com/c/go/+/203824 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/runtime/signal_ppc64x.go')
-rw-r--r--src/runtime/signal_ppc64x.go24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/runtime/signal_ppc64x.go b/src/runtime/signal_ppc64x.go
index 7befad40d2..b879ea5269 100644
--- a/src/runtime/signal_ppc64x.go
+++ b/src/runtime/signal_ppc64x.go
@@ -86,8 +86,28 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
c.set_pc(uint64(funcPC(sigpanic)))
}
-const pushCallSupported = false
+const pushCallSupported = true
func (c *sigctxt) pushCall(targetPC uintptr) {
- throw("not implemented")
+ // Push the LR to stack, as we'll clobber it in order to
+ // push the call. The function being pushed is responsible
+ // for restoring the LR and setting the SP back.
+ // This extra space is known to gentraceback.
+ sp := c.sp() - sys.MinFrameSize
+ c.set_sp(sp)
+ *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link()
+ // In PIC mode, we'll set up (i.e. clobber) R2 on function
+ // entry. Save it ahead of time.
+ // In PIC mode it requires R12 points to the function entry,
+ // so we'll set it up when pushing the call. Save it ahead
+ // of time as well.
+ // 8(SP) and 16(SP) are unused space in the reserved
+ // MinFrameSize (32) bytes.
+ *(*uint64)(unsafe.Pointer(uintptr(sp) + 8)) = c.r2()
+ *(*uint64)(unsafe.Pointer(uintptr(sp) + 16)) = c.r12()
+ // Set up PC and LR to pretend the function being signaled
+ // calls targetPC at the faulting PC.
+ c.set_link(c.pc())
+ c.set_r12(uint64(targetPC))
+ c.set_pc(uint64(targetPC))
}