1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (C) 2021 ARM Limited.
3 // Original author: Mark Brown <broonie@kernel.org>
5 // Scalable Matrix Extension ZA context switch test
6 // Repeatedly writes unique test patterns into each ZA tile
7 // and reads them back to verify integrity.
9 // for x in `seq 1 NR_CPUS`; do sve-test & pids=$pids\ $! ; done
10 // (leave it running for as long as you want...)
13 #include <asm/unistd.h>
14 #include "assembler.h"
15 #include "asm-offsets.h"
21 #define MAXVL_B (MAXVL / 8)
23 // Declare some storage space to shadow ZA register contents and a
24 // scratch buffer for a vector.
29 .space MAXVL_B * MAXVL_B
34 // Trivial memory copy: copy x2 bytes, starting at address x1, to address x0.
46 // Generate a test pattern for storage in ZA
51 // These values are used to constuct a 32-bit pattern that is repeated in the
52 // scratch buffer as many times as will fit:
53 // bits 31:28 generation number (increments once per test_loop)
55 // bits 15: 8 row number
56 // bits 7: 0 32-bit lane index
60 bfi w3, w0, #16, #12 // PID
61 bfi w3, w1, #8, #8 // Row
62 bfi w3, w2, #28, #4 // Generation
68 add w3, w3, #1 // Lane
75 // Get the address of shadow data for ZA horizontal vector xn
76 .macro _adrza xd, xn, nrtmp
79 madd \xd, x\nrtmp, \xn, \xd
82 // Set up test pattern in a ZA horizontal vector
88 mov x12, x1 // Use x12 for vector select
90 bl pattern // Get pattern in scratch buffer
91 _adrza x0, x12, 2 // Shadow buffer pointer to x0 and x5
94 bl memcpy // length set up in x2 by _adrza
96 _ldr_za 12, 5 // load vector w12 from pointer x5
101 // Trivial memory compare: compare x2 bytes starting at address x0 with
102 // bytes starting at address x1.
103 // Returns only if all bytes match; otherwise, the program is aborted.
108 stp x0, x1, [sp, #-0x20]!
120 1: ldr x2, [sp, #0x10]
121 ldp x0, x1, [sp], #0x20
127 // Verify that a ZA vector matches its shadow in memory, else abort
129 // Clobbers x0-x7 and x12.
134 _adrza x5, x0, 6 // pointer to expected value in x5
136 ldr x7, =scratch // x7 is scratch
138 mov x0, x7 // Poison scratch
142 _str_za 12, 7 // save vector w12 to pointer x7
151 // Any SME register modified here can cause corruption in the main
152 // thread -- but *only* the locations modified here.
153 function irritator_handler
154 // Increment the irritation signal count (x23):
155 ldr x0, [x2, #ucontext_regs + 8 * 23]
157 str x0, [x2, #ucontext_regs + 8 * 23]
159 // Corrupt some random ZA data
161 adr x0, .text + (irritator_handler - .text) / 16 * 16
170 function terminate_handler
174 puts "Terminated by signal "
177 puts ", no error, iterations="
178 ldr x0, [x20, #ucontext_regs + 8 * 22]
181 ldr x0, [x20, #ucontext_regs + 8 * 23]
194 str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
206 str w6, [x1, #sa_flags]
207 str x5, [x1, #sa_handler]
210 mov x8, #__NR_rt_sigaction
215 puts "sigaction failure\n"
218 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
222 // Main program entry point
226 puts "Streaming mode "
229 // Sanity-check and report the vector length
239 1: puts "bad vector length: "
244 2: puts "vector length:\t"
249 // Obtain our PID, to ensure test pattern uniqueness between processes
258 mov x23, #0 // Irritation signal count
261 adr x1, terminate_handler
266 adr x1, terminate_handler
271 adr x1, irritator_handler
273 orr w2, w2, #SA_NODEFER
276 mov x22, #0 // generation number, increments per iteration
282 rdsvl 21, 1 // Set up ZA & shadow with test pattern
290 and x8, x22, #127 // Every 128 interations...
292 mov x8, #__NR_getpid // (otherwise minimal syscall)
295 mov x8, #__NR_sched_yield // ...encourage preemption
299 mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=1,SM=0
304 rdsvl 21, 1 // Verify that the data made it through
305 rdsvl 24, 1 // Verify that the data made it through
311 add x22, x22, #1 // Everything still working
322 // fpsimd.c acitivty log dump hack
323 // ldr w0, =0xdeadc0de
324 // mov w8, #__NR_exit
328 mov x10, x0 // expected data
329 mov x11, x1 // actual data
330 mov x12, x2 // data size
332 puts "Mismatch: PID="
353 // fpsimd.c acitivty log dump hack
354 // ldr w0, =0xdeadc0de
355 // mov w8, #__NR_exit
361 // mov x8, #__NR_exit
369 puts "Bad active VL: "