diff options
author | Cherry Zhang <cherryyz@google.com> | 2019-10-28 00:53:14 -0400 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2019-11-08 16:44:48 +0000 |
commit | 374c2847f9c03da7365bfb78e5ef96a0cb837656 (patch) | |
tree | d53e66576fc42b184a39be7569fe1bacdea70f85 /src/runtime/signal_ppc64x.go | |
parent | 7f574e476ac4a6e8c2719b9674ee7b3786bb8401 (diff) | |
download | go-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.go | 24 |
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)) } |