1 // Copyright 2026 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 //go:build goexperiment.runtimesecret
6
7 // Note: this assembly file is used for testing only.
8 // We need to access registers directly to properly test
9 // that secrets are erased and go test doesn't like to conditionally
10 // include assembly files.
11 // These functions defined in the package proper and we
12 // rely on the linker to prune these away in regular builds
13
14 #include "go_asm.h"
15 #include "funcdata.h"
16
17 #define REGTMP1 R27
18 #define REGTMP2 R28
19
20 #define dirtyReg(dstReg) \
21 ADDV $0x1, REGTMP1 \
22 MOVV REGTMP1, dstReg \
23
24
25 #define dirtyVReg(dstReg) \
26 ADDV $0x1, REGTMP1 \
27 VMOVQ REGTMP1, dstReg.V2 \
28
29
30 #define dirtyXReg(dstReg) \
31 ADDV $0x1, REGTMP1 \
32 XVMOVQ REGTMP1, dstReg.V4 \
33
34
35 // func loadRegisters(p unsafe.Pointer)
36 TEXT ·loadRegisters(SB),0,$0-8
37 MOVV p+0(FP), R4
38
39 MOVV (R4), R16
40 MOVV (R4), R17
41 MOVV (R4), R18
42 MOVV (R4), R19
43
44 MOVD (R4), F20
45 MOVD (R4), F21
46 MOVD (R4), F22
47 MOVD (R4), F23
48
49 MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLSX(SB), R5
50 BEQ R5, return
51 VMOVQ (R4), V24
52 VMOVQ (R4), V25
53 VMOVQ (R4), V26
54 VMOVQ (R4), V27
55
56 MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLASX(SB), R5
57 BEQ R5, return
58 XVMOVQ (R4), X28
59 XVMOVQ (R4), X29
60 XVMOVQ (R4), X30
61 XVMOVQ (R4), X31
62 return:
63 RET
64
65 // func spillRegisters(p unsafe.Pointer) uintptr
66 TEXT ·spillRegisters(SB),0,$0-16
67 MOVV p+0(FP), R4
68 MOVV $0, R5
69
70 MOVV R16, 0(R4)
71 MOVV R17, 8(R4)
72 MOVV R18, 16(R4)
73 MOVV R19, 24(R4)
74
75 MOVD F20, 32(R4)
76 MOVD F21, 40(R4)
77 MOVD F22, 48(R4)
78 MOVD F23, 56(R4)
79 ADDV $64, R4
80 ADDV $64, R5
81
82 MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLSX(SB), R6
83 BEQ R6, return
84 VMOVQ V24, 0(R4)
85 VMOVQ V25, 16(R4)
86 VMOVQ V26, 32(R4)
87 VMOVQ V27, 48(R4)
88 ADDV $64, R4
89 ADDV $64, R5
90
91 MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLASX(SB), R6
92 BEQ R6, return
93 XVMOVQ X28, 0(R4)
94 XVMOVQ X29, 32(R4)
95 XVMOVQ X30, 64(R4)
96 XVMOVQ X31, 96(R4)
97 ADDV $128, R4
98 ADDV $128, R5
99 return:
100 MOVV R5, ret+8(FP)
101 RET
102
103 TEXT ·useSecret(SB),0,$0-24
104 NO_LOCAL_POINTERS
105
106 // Load secret into R27
107 MOVV secret_base+0(FP), REGTMP2
108 MOVV (REGTMP2), REGTMP1
109
110 MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLASX(SB), REGTMP2
111 BNE REGTMP2, dirtyLASX
112
113 MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLSX(SB), REGTMP2
114 BNE REGTMP2, dirtyLSX
115
116 // Dirty the floating point registers
117 dirtyReg(F0)
118 dirtyReg(F1)
119 dirtyReg(F2)
120 dirtyReg(F3)
121 dirtyReg(F4)
122 dirtyReg(F5)
123 dirtyReg(F6)
124 dirtyReg(F7)
125 dirtyReg(F8)
126 dirtyReg(F9)
127 dirtyReg(F10)
128 dirtyReg(F11)
129 dirtyReg(F12)
130 dirtyReg(F13)
131 dirtyReg(F14)
132 dirtyReg(F15)
133 dirtyReg(F16)
134 dirtyReg(F17)
135 dirtyReg(F18)
136 dirtyReg(F19)
137 dirtyReg(F20)
138 dirtyReg(F21)
139 dirtyReg(F22)
140 dirtyReg(F23)
141 dirtyReg(F24)
142 dirtyReg(F25)
143 dirtyReg(F26)
144 dirtyReg(F27)
145 dirtyReg(F28)
146 dirtyReg(F29)
147 dirtyReg(F30)
148 dirtyReg(F31)
149 JMP dirtyInt
150
151 // Dirty the lsx registers
152 dirtyLSX:
153 dirtyVReg(V0)
154 dirtyVReg(V1)
155 dirtyVReg(V2)
156 dirtyVReg(V3)
157 dirtyVReg(V4)
158 dirtyVReg(V5)
159 dirtyVReg(V6)
160 dirtyVReg(V7)
161 dirtyVReg(V8)
162 dirtyVReg(V9)
163 dirtyVReg(V10)
164 dirtyVReg(V11)
165 dirtyVReg(V12)
166 dirtyVReg(V13)
167 dirtyVReg(V14)
168 dirtyVReg(V15)
169 dirtyVReg(V16)
170 dirtyVReg(V17)
171 dirtyVReg(V18)
172 dirtyVReg(V19)
173 dirtyVReg(V20)
174 dirtyVReg(V21)
175 dirtyVReg(V22)
176 dirtyVReg(V23)
177 dirtyVReg(V24)
178 dirtyVReg(V25)
179 dirtyVReg(V26)
180 dirtyVReg(V27)
181 dirtyVReg(V28)
182 dirtyVReg(V29)
183 dirtyVReg(V30)
184 dirtyVReg(V31)
185 JMP dirtyInt
186
187 // Dirty the lasx registers
188 dirtyLASX:
189 dirtyXReg(X0)
190 dirtyXReg(X1)
191 dirtyXReg(X2)
192 dirtyXReg(X3)
193 dirtyXReg(X4)
194 dirtyXReg(X5)
195 dirtyXReg(X6)
196 dirtyXReg(X7)
197 dirtyXReg(X8)
198 dirtyXReg(X9)
199 dirtyXReg(X10)
200 dirtyXReg(X11)
201 dirtyXReg(X12)
202 dirtyXReg(X13)
203 dirtyXReg(X14)
204 dirtyXReg(X15)
205 dirtyXReg(X16)
206 dirtyXReg(X17)
207 dirtyXReg(X18)
208 dirtyXReg(X19)
209 dirtyXReg(X20)
210 dirtyXReg(X21)
211 dirtyXReg(X22)
212 dirtyXReg(X23)
213 dirtyXReg(X24)
214 dirtyXReg(X25)
215 dirtyXReg(X26)
216 dirtyXReg(X27)
217 dirtyXReg(X28)
218 dirtyXReg(X29)
219 dirtyXReg(X30)
220 dirtyXReg(X31)
221
222 dirtyInt:
223 // Scatter secret across registers.
224 // Increment low byte so we can tell which register
225 // a leaking secret came from.
226 dirtyReg(R4)
227 dirtyReg(R5)
228 dirtyReg(R6)
229 dirtyReg(R7)
230 dirtyReg(R8)
231 dirtyReg(R9)
232 dirtyReg(R10)
233 dirtyReg(R11)
234 dirtyReg(R12)
235 dirtyReg(R13)
236 dirtyReg(R14)
237 dirtyReg(R15)
238 dirtyReg(R16)
239 dirtyReg(R17)
240 dirtyReg(R18)
241 dirtyReg(R19)
242 RET
243
View as plain text