Linux Audio

Check our new training course

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