Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / testing / selftests / arm64 / fp / zt-test.S
blob38080f3c328042af6b3e2d7c3300162ea6efa4ea
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.
9 #include <asm/unistd.h>
10 #include "assembler.h"
11 #include "asm-offsets.h"
12 #include "sme-inst.h"
14 .arch_extension sve
16 #define ZT_SZ   512
17 #define ZT_B    (ZT_SZ / 8)
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
31 // Generate a test pattern for storage in ZT
32 // x0: pid
33 // x1: generation
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
41 function pattern
42         mov     w3, wzr
43         bfi     w3, w0, #8, #16         // PID
44         bfi     w3, w1, #24, #8         // Generation
46         ldr     x0, =scratch
47         mov     w1, #ZT_B / 4
49 0:      str     w3, [x0], #4
50         add     w3, w3, #1              // Lane
51         subs    w1, w1, #1
52         b.ne    0b
54         ret
55 endfunction
57 // Set up test pattern in a ZT horizontal vector
58 // x0: pid
59 // x1: generation
60 function setup_zt
61         mov     x4, x30
63         bl      pattern                 // Get pattern in scratch buffer
64         ldr     x0, =ztref
65         ldr     x1, =scratch
66         mov     x2, #ZT_B
67         bl      memcpy
69         ldr     x0, =ztref
70         _ldr_zt 0                       // load zt0 from pointer x0
72         ret     x4
73 endfunction
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
82         stp     x0, x1, [sp, #-0x20]!
83         str     x2, [sp, #0x10]
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
94 1:      ldr     x2, [sp, #0x10]
95         ldp     x0, x1, [sp], #0x20
96         b.ne    barf
98 2:      ret
99 endfunction
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
106         ldr     x0, =scratch            // Poison scratch
107         mov     x1, #ZT_B
108         bl      memfill_ae
110         ldr     x0, =scratch
111         _str_zt 0
113         ldr     x0, =ztref
114         ldr     x1, =scratch
115         mov     x2, #ZT_B
116         mov     x30, x3
117         b       memcmp
118 endfunction
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]
127         // This will reset ZT to all bits 0
128         smstop
129         smstart_za
131         ret
132 endfunction
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]
140         ret
141 endfunction
143 function terminate_handler
144         mov     w21, w0
145         mov     x20, x2
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
157         mov     x0, #0
158         mov     x8, #__NR_exit
159         svc     #0
160 endfunction
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)]!
169         mov     w4, w0
170         mov     x5, x1
171         mov     w6, w2
173         add     x0, sp, #16
174         mov     x1, #sa_sz
175         bl      memclr
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
186         cbz     w0, 1f
188         puts    "sigaction failure\n"
189         b       .Labort
191 1:      ldr     x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
192         ret
193 endfunction
195 // Main program entry point
196 .globl _start
197 function _start
198         enable_gcs
200         mov     x23, #0         // signal count
202         mov     w0, #SIGINT
203         adr     x1, terminate_handler
204         mov     w2, #SA_SIGINFO
205         bl      setsignal
207         mov     w0, #SIGTERM
208         adr     x1, terminate_handler
209         mov     w2, #SA_SIGINFO
210         bl      setsignal
212         mov     w0, #SIGUSR1
213         adr     x1, irritator_handler
214         mov     w2, #SA_SIGINFO
215         orr     w2, w2, #SA_NODEFER
216         bl      setsignal
218         mov     w0, #SIGUSR2
219         adr     x1, tickle_handler
220         mov     w2, #SA_SIGINFO
221         orr     w2, w2, #SA_NODEFER
222         bl      setsignal
224         smstart_za
226         // Obtain our PID, to ensure test pattern uniqueness between processes
227         mov     x8, #__NR_getpid
228         svc     #0
229         mov     x20, x0
231         puts    "PID:\t"
232         mov     x0, x20
233         bl      putdecn
235         mov     x22, #0         // generation number, increments per iteration
236 .Ltest_loop:
237         mov     x0, x20
238         mov     x1, x22
239         bl      setup_zt
241         mov     x8, #__NR_sched_yield   // Encourage preemption
242         svc     #0
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
249         bl      check_zt
251         add     x22, x22, #1    // Everything still working
252         b       .Ltest_loop
254 .Labort:
255         mov     x0, #0
256         mov     x1, #SIGABRT
257         mov     x8, #__NR_kill
258         svc     #0
259 endfunction
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
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
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
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
308 function svcr_barf
309         mov     x10, x0
311         puts    "Bad SVCR: "
312         mov     x0, x10
313         bl      putdecn
315         mov     x8, #__NR_exit
316         mov     x1, #1
317         svc     #0
318 endfunction