Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/arm64/fp/zt-test.S
26289 views
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
24
ztref:
25
.space ZT_B
26
scratch:
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
41
function 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
49
0: str w3, [x0], #4
50
add w3, w3, #1 // Lane
51
subs w1, w1, #1
52
b.ne 0b
53
54
ret
55
endfunction
56
57
// Set up test pattern in a ZT horizontal vector
58
// x0: pid
59
// x1: generation
60
function 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
73
endfunction
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.
79
function memcmp
80
cbz x2, 2f
81
82
stp x0, x1, [sp, #-0x20]!
83
str x2, [sp, #0x10]
84
85
mov x5, #0
86
0: 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
94
1: ldr x2, [sp, #0x10]
95
ldp x0, x1, [sp], #0x20
96
b.ne barf
97
98
2: ret
99
endfunction
100
101
// Verify that a ZT vector matches its shadow in memory, else abort
102
// Clobbers x0-x3
103
function 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
118
endfunction
119
120
// Modify the live SME register state, signal return will undo our changes
121
function irritator_handler
122
// Increment the irritation signal count (x23):
123
ldr x0, [x2, #ucontext_regs + 8 * 23]
124
add x0, x0, #1
125
str x0, [x2, #ucontext_regs + 8 * 23]
126
127
// This will reset ZT to all bits 0
128
smstop
129
smstart_za
130
131
ret
132
endfunction
133
134
function tickle_handler
135
// Increment the signal count (x23):
136
ldr x0, [x2, #ucontext_regs + 8 * 23]
137
add x0, x0, #1
138
str x0, [x2, #ucontext_regs + 8 * 23]
139
140
ret
141
endfunction
142
143
function terminate_handler
144
mov w21, w0
145
mov x20, x2
146
147
puts "Terminated by signal "
148
mov w0, w21
149
bl putdec
150
puts ", no error, iterations="
151
ldr x0, [x20, #ucontext_regs + 8 * 22]
152
bl putdec
153
puts ", signals="
154
ldr x0, [x20, #ucontext_regs + 8 * 23]
155
bl putdecn
156
157
mov x0, #0
158
mov x8, #__NR_exit
159
svc #0
160
endfunction
161
162
// w0: signal number
163
// x1: sa_action
164
// w2: sa_flags
165
// Clobbers x0-x6,x8
166
function setsignal
167
str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
168
169
mov w4, w0
170
mov x5, x1
171
mov w6, w2
172
173
add x0, sp, #16
174
mov x1, #sa_sz
175
bl memclr
176
177
mov w0, w4
178
add x1, sp, #16
179
str w6, [x1, #sa_flags]
180
str x5, [x1, #sa_handler]
181
mov x2, #0
182
mov x3, #sa_mask_sz
183
mov x8, #__NR_rt_sigaction
184
svc #0
185
186
cbz w0, 1f
187
188
puts "sigaction failure\n"
189
b .Labort
190
191
1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
192
ret
193
endfunction
194
195
// Main program entry point
196
.globl _start
197
function _start
198
enable_gcs
199
200
mov x23, #0 // signal count
201
202
mov w0, #SIGINT
203
adr x1, terminate_handler
204
mov w2, #SA_SIGINFO
205
bl setsignal
206
207
mov w0, #SIGTERM
208
adr x1, terminate_handler
209
mov w2, #SA_SIGINFO
210
bl setsignal
211
212
mov w0, #SIGUSR1
213
adr x1, irritator_handler
214
mov w2, #SA_SIGINFO
215
orr w2, w2, #SA_NODEFER
216
bl setsignal
217
218
mov w0, #SIGUSR2
219
adr x1, tickle_handler
220
mov w2, #SA_SIGINFO
221
orr w2, w2, #SA_NODEFER
222
bl setsignal
223
224
smstart_za
225
226
// Obtain our PID, to ensure test pattern uniqueness between processes
227
mov x8, #__NR_getpid
228
svc #0
229
mov x20, x0
230
231
puts "PID:\t"
232
mov x0, x20
233
bl putdecn
234
235
mov x22, #0 // generation number, increments per iteration
236
.Ltest_loop:
237
mov x0, x20
238
mov x1, x22
239
bl setup_zt
240
241
mov x8, #__NR_sched_yield // Encourage preemption
242
svc #0
243
244
mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=1,SM=0
245
and x1, x0, #3
246
cmp x1, #2
247
b.ne svcr_barf
248
249
bl check_zt
250
251
add x22, x22, #1 // Everything still working
252
b .Ltest_loop
253
254
.Labort:
255
mov x0, #0
256
mov x1, #SIGABRT
257
mov x8, #__NR_kill
258
svc #0
259
endfunction
260
261
function barf
262
// fpsimd.c acitivty log dump hack
263
// ldr w0, =0xdeadc0de
264
// mov w8, #__NR_exit
265
// svc #0
266
// end hack
267
268
mrs x13, S3_3_C4_C2_2
269
smstop
270
mov x10, x0 // expected data
271
mov x11, x1 // actual data
272
mov x12, x2 // data size
273
274
puts "Mismatch: PID="
275
mov x0, x20
276
bl putdec
277
puts ", iteration="
278
mov x0, x22
279
bl putdec
280
puts "\tExpected ["
281
mov x0, x10
282
mov x1, x12
283
bl dumphex
284
puts "]\n\tGot ["
285
mov x0, x11
286
mov x1, x12
287
bl dumphex
288
puts "]\n"
289
puts "\tSVCR: "
290
mov x0, x13
291
bl putdecn
292
293
mov x8, #__NR_getpid
294
svc #0
295
// fpsimd.c acitivty log dump hack
296
// ldr w0, =0xdeadc0de
297
// mov w8, #__NR_exit
298
// svc #0
299
// ^ end of hack
300
mov x1, #SIGABRT
301
mov x8, #__NR_kill
302
svc #0
303
// mov x8, #__NR_exit
304
// mov x1, #1
305
// svc #0
306
endfunction
307
308
function svcr_barf
309
mov x10, x0
310
311
puts "Bad SVCR: "
312
mov x0, x10
313
bl putdecn
314
315
mov x8, #__NR_exit
316
mov x1, #1
317
svc #0
318
endfunction
319
320