Loading...
1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (C) 2021-2 ARM Limited.
3// Original author: Mark Brown <broonie@kernel.org>
4//
5// Scalable Matrix Extension ZT context switch test
6// Repeatedly writes unique test patterns into ZT0
7// and reads them back to verify integrity.
8
9#include <asm/unistd.h>
10#include "assembler.h"
11#include "asm-offsets.h"
12#include "sme-inst.h"
13
14.arch_extension sve
15
16#define ZT_SZ 512
17#define ZT_B (ZT_SZ / 8)
18
19// Declare some storage space to shadow ZT register contents and a
20// scratch buffer.
21.pushsection .text
22.data
23.align 4
24ztref:
25 .space ZT_B
26scratch:
27 .space ZT_B
28.popsection
29
30
31// Generate a test pattern for storage in ZT
32// x0: pid
33// x1: generation
34
35// These values are used to construct a 32-bit pattern that is repeated in the
36// scratch buffer as many times as will fit:
37// bits 31:24 generation number (increments once per test_loop)
38// bits 23: 8 pid
39// bits 7: 0 32-bit lane index
40
41function pattern
42 mov w3, wzr
43 bfi w3, w0, #8, #16 // PID
44 bfi w3, w1, #24, #8 // Generation
45
46 ldr x0, =scratch
47 mov w1, #ZT_B / 4
48
490: str w3, [x0], #4
50 add w3, w3, #1 // Lane
51 subs w1, w1, #1
52 b.ne 0b
53
54 ret
55endfunction
56
57// Set up test pattern in a ZT horizontal vector
58// x0: pid
59// x1: generation
60function setup_zt
61 mov x4, x30
62
63 bl pattern // Get pattern in scratch buffer
64 ldr x0, =ztref
65 ldr x1, =scratch
66 mov x2, #ZT_B
67 bl memcpy
68
69 ldr x0, =ztref
70 _ldr_zt 0 // load zt0 from pointer x0
71
72 ret x4
73endfunction
74
75// Trivial memory compare: compare x2 bytes starting at address x0 with
76// bytes starting at address x1.
77// Returns only if all bytes match; otherwise, the program is aborted.
78// Clobbers x0-x5.
79function memcmp
80 cbz x2, 2f
81
82 stp x0, x1, [sp, #-0x20]!
83 str x2, [sp, #0x10]
84
85 mov x5, #0
860: ldrb w3, [x0, x5]
87 ldrb w4, [x1, x5]
88 add x5, x5, #1
89 cmp w3, w4
90 b.ne 1f
91 subs x2, x2, #1
92 b.ne 0b
93
941: ldr x2, [sp, #0x10]
95 ldp x0, x1, [sp], #0x20
96 b.ne barf
97
982: ret
99endfunction
100
101// Verify that a ZT vector matches its shadow in memory, else abort
102// Clobbers x0-x3
103function check_zt
104 mov x3, x30
105
106 ldr x0, =scratch // Poison scratch
107 mov x1, #ZT_B
108 bl memfill_ae
109
110 ldr x0, =scratch
111 _str_zt 0
112
113 ldr x0, =ztref
114 ldr x1, =scratch
115 mov x2, #ZT_B
116 mov x30, x3
117 b memcmp
118endfunction
119
120// Any SME register modified here can cause corruption in the main
121// thread -- but *only* the locations modified here.
122function irritator_handler
123 // Increment the irritation signal count (x23):
124 ldr x0, [x2, #ucontext_regs + 8 * 23]
125 add x0, x0, #1
126 str x0, [x2, #ucontext_regs + 8 * 23]
127
128 // Corrupt some random ZT data
129#if 0
130 adr x0, .text + (irritator_handler - .text) / 16 * 16
131 movi v0.8b, #1
132 movi v9.16b, #2
133 movi v31.8b, #3
134#endif
135
136 ret
137endfunction
138
139function tickle_handler
140 // Increment the signal count (x23):
141 ldr x0, [x2, #ucontext_regs + 8 * 23]
142 add x0, x0, #1
143 str x0, [x2, #ucontext_regs + 8 * 23]
144
145 ret
146endfunction
147
148function terminate_handler
149 mov w21, w0
150 mov x20, x2
151
152 puts "Terminated by signal "
153 mov w0, w21
154 bl putdec
155 puts ", no error, iterations="
156 ldr x0, [x20, #ucontext_regs + 8 * 22]
157 bl putdec
158 puts ", signals="
159 ldr x0, [x20, #ucontext_regs + 8 * 23]
160 bl putdecn
161
162 mov x0, #0
163 mov x8, #__NR_exit
164 svc #0
165endfunction
166
167// w0: signal number
168// x1: sa_action
169// w2: sa_flags
170// Clobbers x0-x6,x8
171function setsignal
172 str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
173
174 mov w4, w0
175 mov x5, x1
176 mov w6, w2
177
178 add x0, sp, #16
179 mov x1, #sa_sz
180 bl memclr
181
182 mov w0, w4
183 add x1, sp, #16
184 str w6, [x1, #sa_flags]
185 str x5, [x1, #sa_handler]
186 mov x2, #0
187 mov x3, #sa_mask_sz
188 mov x8, #__NR_rt_sigaction
189 svc #0
190
191 cbz w0, 1f
192
193 puts "sigaction failure\n"
194 b .Labort
195
1961: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
197 ret
198endfunction
199
200// Main program entry point
201.globl _start
202function _start
203 mov x23, #0 // signal count
204
205 mov w0, #SIGINT
206 adr x1, terminate_handler
207 mov w2, #SA_SIGINFO
208 bl setsignal
209
210 mov w0, #SIGTERM
211 adr x1, terminate_handler
212 mov w2, #SA_SIGINFO
213 bl setsignal
214
215 mov w0, #SIGUSR1
216 adr x1, irritator_handler
217 mov w2, #SA_SIGINFO
218 orr w2, w2, #SA_NODEFER
219 bl setsignal
220
221 mov w0, #SIGUSR2
222 adr x1, tickle_handler
223 mov w2, #SA_SIGINFO
224 orr w2, w2, #SA_NODEFER
225 bl setsignal
226
227 smstart_za
228
229 // Obtain our PID, to ensure test pattern uniqueness between processes
230 mov x8, #__NR_getpid
231 svc #0
232 mov x20, x0
233
234 puts "PID:\t"
235 mov x0, x20
236 bl putdecn
237
238 mov x22, #0 // generation number, increments per iteration
239.Ltest_loop:
240 mov x0, x20
241 mov x1, x22
242 bl setup_zt
243
244 mov x8, #__NR_sched_yield // Encourage preemption
245 svc #0
246
247 mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=1,SM=0
248 and x1, x0, #3
249 cmp x1, #2
250 b.ne svcr_barf
251
252 bl check_zt
253
254 add x22, x22, #1 // Everything still working
255 b .Ltest_loop
256
257.Labort:
258 mov x0, #0
259 mov x1, #SIGABRT
260 mov x8, #__NR_kill
261 svc #0
262endfunction
263
264function barf
265// fpsimd.c acitivty log dump hack
266// ldr w0, =0xdeadc0de
267// mov w8, #__NR_exit
268// svc #0
269// end hack
270
271 mrs x13, S3_3_C4_C2_2
272 smstop
273 mov x10, x0 // expected data
274 mov x11, x1 // actual data
275 mov x12, x2 // data size
276
277 puts "Mismatch: PID="
278 mov x0, x20
279 bl putdec
280 puts ", iteration="
281 mov x0, x22
282 bl putdec
283 puts "\tExpected ["
284 mov x0, x10
285 mov x1, x12
286 bl dumphex
287 puts "]\n\tGot ["
288 mov x0, x11
289 mov x1, x12
290 bl dumphex
291 puts "]\n"
292 puts "\tSVCR: "
293 mov x0, x13
294 bl putdecn
295
296 mov x8, #__NR_getpid
297 svc #0
298// fpsimd.c acitivty log dump hack
299// ldr w0, =0xdeadc0de
300// mov w8, #__NR_exit
301// svc #0
302// ^ end of hack
303 mov x1, #SIGABRT
304 mov x8, #__NR_kill
305 svc #0
306// mov x8, #__NR_exit
307// mov x1, #1
308// svc #0
309endfunction
310
311function svcr_barf
312 mov x10, x0
313
314 puts "Bad SVCR: "
315 mov x0, x10
316 bl putdecn
317
318 mov x8, #__NR_exit
319 mov x1, #1
320 svc #0
321endfunction