Skip to content

Commit 08ba718

Browse files
committed
runtime: add async preemption support on riscv64
This CL adds support of call injection and async preemption on riscv64. We also clobbered REG_TMP for the injected call. Unsafe points related to REG_TMP access have been marked in previous commits. Fixes #36711.
1 parent 6d0451f commit 08ba718

File tree

3 files changed

+162
-6
lines changed

3 files changed

+162
-6
lines changed

src/runtime/mkpreempt.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,35 @@ func genPPC64() {
502502
}
503503

504504
func genRISCV64() {
505-
p("// No async preemption on riscv64 - see issue 36711")
506-
p("UNDEF")
505+
// X0 (zero), X1 (LR), X2 (SP), X4 (g), X31 (TMP) are special.
506+
var l = layout{sp: "X2", stack: 8}
507+
508+
// Integers
509+
for i := 3; i < 31; i++ {
510+
if i == 4 {
511+
continue
512+
}
513+
reg := fmt.Sprintf("X%d", i)
514+
l.add("MOV", reg, 8)
515+
}
516+
517+
// Floating points
518+
// TODO: support fscr.
519+
for i := 0; i <= 31; i++ {
520+
reg := fmt.Sprintf("F%d", i)
521+
l.add("MOVF", reg, 8)
522+
}
523+
524+
p("MOV X1, -%d(X2)", l.stack)
525+
p("ADD $-%d, X2", l.stack)
526+
l.save()
527+
p("CALL ·asyncPreempt2(SB)")
528+
l.restore()
529+
p("MOV %d(X2), X31", l.stack)
530+
p("ADD $%d, X2", l.stack+8)
531+
p("MOV 0(X2), X1")
532+
533+
p("JMP 0(X31)")
507534
}
508535

509536
func genS390X() {

src/runtime/preempt_riscv64.s

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,128 @@
44
#include "textflag.h"
55

66
TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
7-
// No async preemption on riscv64 - see issue 36711
8-
UNDEF
7+
MOV X1, -480(X2)
8+
ADD $-480, X2
9+
MOV X3, 8(X2)
10+
MOV X5, 16(X2)
11+
MOV X6, 24(X2)
12+
MOV X7, 32(X2)
13+
MOV X8, 40(X2)
14+
MOV X9, 48(X2)
15+
MOV X10, 56(X2)
16+
MOV X11, 64(X2)
17+
MOV X12, 72(X2)
18+
MOV X13, 80(X2)
19+
MOV X14, 88(X2)
20+
MOV X15, 96(X2)
21+
MOV X16, 104(X2)
22+
MOV X17, 112(X2)
23+
MOV X18, 120(X2)
24+
MOV X19, 128(X2)
25+
MOV X20, 136(X2)
26+
MOV X21, 144(X2)
27+
MOV X22, 152(X2)
28+
MOV X23, 160(X2)
29+
MOV X24, 168(X2)
30+
MOV X25, 176(X2)
31+
MOV X26, 184(X2)
32+
MOV X27, 192(X2)
33+
MOV X28, 200(X2)
34+
MOV X29, 208(X2)
35+
MOV X30, 216(X2)
36+
MOVF F0, 224(X2)
37+
MOVF F1, 232(X2)
38+
MOVF F2, 240(X2)
39+
MOVF F3, 248(X2)
40+
MOVF F4, 256(X2)
41+
MOVF F5, 264(X2)
42+
MOVF F6, 272(X2)
43+
MOVF F7, 280(X2)
44+
MOVF F8, 288(X2)
45+
MOVF F9, 296(X2)
46+
MOVF F10, 304(X2)
47+
MOVF F11, 312(X2)
48+
MOVF F12, 320(X2)
49+
MOVF F13, 328(X2)
50+
MOVF F14, 336(X2)
51+
MOVF F15, 344(X2)
52+
MOVF F16, 352(X2)
53+
MOVF F17, 360(X2)
54+
MOVF F18, 368(X2)
55+
MOVF F19, 376(X2)
56+
MOVF F20, 384(X2)
57+
MOVF F21, 392(X2)
58+
MOVF F22, 400(X2)
59+
MOVF F23, 408(X2)
60+
MOVF F24, 416(X2)
61+
MOVF F25, 424(X2)
62+
MOVF F26, 432(X2)
63+
MOVF F27, 440(X2)
64+
MOVF F28, 448(X2)
65+
MOVF F29, 456(X2)
66+
MOVF F30, 464(X2)
67+
MOVF F31, 472(X2)
68+
CALL ·asyncPreempt2(SB)
69+
MOVF 472(X2), F31
70+
MOVF 464(X2), F30
71+
MOVF 456(X2), F29
72+
MOVF 448(X2), F28
73+
MOVF 440(X2), F27
74+
MOVF 432(X2), F26
75+
MOVF 424(X2), F25
76+
MOVF 416(X2), F24
77+
MOVF 408(X2), F23
78+
MOVF 400(X2), F22
79+
MOVF 392(X2), F21
80+
MOVF 384(X2), F20
81+
MOVF 376(X2), F19
82+
MOVF 368(X2), F18
83+
MOVF 360(X2), F17
84+
MOVF 352(X2), F16
85+
MOVF 344(X2), F15
86+
MOVF 336(X2), F14
87+
MOVF 328(X2), F13
88+
MOVF 320(X2), F12
89+
MOVF 312(X2), F11
90+
MOVF 304(X2), F10
91+
MOVF 296(X2), F9
92+
MOVF 288(X2), F8
93+
MOVF 280(X2), F7
94+
MOVF 272(X2), F6
95+
MOVF 264(X2), F5
96+
MOVF 256(X2), F4
97+
MOVF 248(X2), F3
98+
MOVF 240(X2), F2
99+
MOVF 232(X2), F1
100+
MOVF 224(X2), F0
101+
MOV 216(X2), X30
102+
MOV 208(X2), X29
103+
MOV 200(X2), X28
104+
MOV 192(X2), X27
105+
MOV 184(X2), X26
106+
MOV 176(X2), X25
107+
MOV 168(X2), X24
108+
MOV 160(X2), X23
109+
MOV 152(X2), X22
110+
MOV 144(X2), X21
111+
MOV 136(X2), X20
112+
MOV 128(X2), X19
113+
MOV 120(X2), X18
114+
MOV 112(X2), X17
115+
MOV 104(X2), X16
116+
MOV 96(X2), X15
117+
MOV 88(X2), X14
118+
MOV 80(X2), X13
119+
MOV 72(X2), X12
120+
MOV 64(X2), X11
121+
MOV 56(X2), X10
122+
MOV 48(X2), X9
123+
MOV 40(X2), X8
124+
MOV 32(X2), X7
125+
MOV 24(X2), X6
126+
MOV 16(X2), X5
127+
MOV 8(X2), X3
128+
MOV 480(X2), X31
129+
ADD $488, X2
130+
MOV 0(X2), X1
131+
JMP 0(X31)

src/runtime/signal_riscv64.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,14 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
7878
c.set_pc(uint64(funcPC(sigpanic)))
7979
}
8080

81-
const pushCallSupported = false
81+
const pushCallSupported = true
8282

8383
func (c *sigctxt) pushCall(targetPC uintptr) {
84-
throw("unimplemented")
84+
sp := c.sp() - sys.PtrSize
85+
c.set_sp(sp)
86+
*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.ra()
87+
// Set up PC and LR to pretend the function being signaled
88+
// calls targetPC at the faulting PC.
89+
c.set_ra(c.pc())
90+
c.set_pc(uint64(targetPC))
8591
}

0 commit comments

Comments
 (0)