~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/arm64/fp/fpsimd-test.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 // Copyright (C) 2015-2019 ARM Limited.
  3 // Original author: Dave Martin <Dave.Martin@arm.com>
  4 //
  5 // Simple FPSIMD context switch test
  6 // Repeatedly writes unique test patterns into each FPSIMD register
  7 // and reads them back to verify integrity.
  8 //
  9 // for x in `seq 1 NR_CPUS`; do fpsimd-test & pids=$pids\ $! ; done
 10 // (leave it running for as long as you want...)
 11 // kill $pids
 12 
 13 #include <asm/unistd.h>
 14 #include "assembler.h"
 15 #include "asm-offsets.h"
 16 
 17 #define NVR     32
 18 #define MAXVL_B (128 / 8)
 19 
 20 .macro _vldr Vn:req, Xt:req
 21         ld1     {v\Vn\().2d}, [x\Xt]
 22 .endm
 23 
 24 .macro _vstr Vn:req, Xt:req
 25         st1     {v\Vn\().2d}, [x\Xt]
 26 .endm
 27 
 28 // Generate accessor functions to read/write programmatically selected
 29 // FPSIMD registers.
 30 // x0 is the register index to access
 31 // x1 is the memory address to read from (getv,setp) or store to (setv,setp)
 32 // All clobber x0-x2
 33 define_accessor setv, NVR, _vldr
 34 define_accessor getv, NVR, _vstr
 35 
 36 // Declare some storate space to shadow the SVE register contents:
 37 .pushsection .text
 38 .data
 39 .align 4
 40 vref:
 41         .space  MAXVL_B * NVR
 42 scratch:
 43         .space  MAXVL_B
 44 .popsection
 45 
 46 // Generate a test pattern for storage in SVE registers
 47 // x0: pid      (16 bits)
 48 // x1: register number (6 bits)
 49 // x2: generation (4 bits)
 50 function pattern
 51         orr     w1, w0, w1, lsl #16
 52         orr     w2, w1, w2, lsl #28
 53 
 54         ldr     x0, =scratch
 55         mov     w1, #MAXVL_B / 4
 56 
 57 0:      str     w2, [x0], #4
 58         add     w2, w2, #(1 << 22)
 59         subs    w1, w1, #1
 60         bne     0b
 61 
 62         ret
 63 endfunction
 64 
 65 // Get the address of shadow data for FPSIMD V-register V<xn>
 66 .macro _adrv xd, xn, nrtmp
 67         ldr     \xd, =vref
 68         mov     x\nrtmp, #16
 69         madd    \xd, x\nrtmp, \xn, \xd
 70 .endm
 71 
 72 // Set up test pattern in a FPSIMD V-register
 73 // x0: pid
 74 // x1: register number
 75 // x2: generation
 76 function setup_vreg
 77         mov     x4, x30
 78 
 79         mov     x6, x1
 80         bl      pattern
 81         _adrv   x0, x6, 2
 82         mov     x5, x0
 83         ldr     x1, =scratch
 84         bl      memcpy
 85 
 86         mov     x0, x6
 87         mov     x1, x5
 88         bl      setv
 89 
 90         ret     x4
 91 endfunction
 92 
 93 // Trivial memory compare: compare x2 bytes starting at address x0 with
 94 // bytes starting at address x1.
 95 // Returns only if all bytes match; otherwise, the program is aborted.
 96 // Clobbers x0-x5.
 97 function memcmp
 98         cbz     x2, 1f
 99 
100         mov     x5, #0
101 0:      ldrb    w3, [x0, x5]
102         ldrb    w4, [x1, x5]
103         add     x5, x5, #1
104         cmp     w3, w4
105         b.ne    barf
106         subs    x2, x2, #1
107         b.ne    0b
108 
109 1:      ret
110 endfunction
111 
112 // Verify that a FPSIMD V-register matches its shadow in memory, else abort
113 // x0: reg number
114 // Clobbers x0-x5.
115 function check_vreg
116         mov     x3, x30
117 
118         _adrv   x5, x0, 6
119         mov     x4, x0
120         ldr     x7, =scratch
121 
122         mov     x0, x7
123         mov     x1, x6
124         bl      memfill_ae
125 
126         mov     x0, x4
127         mov     x1, x7
128         bl      getv
129 
130         mov     x0, x5
131         mov     x1, x7
132         mov     x2, x6
133         mov     x30, x3
134         b       memcmp
135 endfunction
136 
137 // Any SVE register modified here can cause corruption in the main
138 // thread -- but *only* the registers modified here.
139 function irritator_handler
140         // Increment the irritation 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         // Corrupt some random V-regs
146         adr     x0, .text + (irritator_handler - .text) / 16 * 16
147         movi    v0.8b, #7
148         movi    v9.16b, #9
149         movi    v31.8b, #31
150 
151         ret
152 endfunction
153 
154 function tickle_handler
155         // Increment the signal count (x23):
156         ldr     x0, [x2, #ucontext_regs + 8 * 23]
157         add     x0, x0, #1
158         str     x0, [x2, #ucontext_regs + 8 * 23]
159 
160         ret
161 endfunction
162 
163 function terminate_handler
164         mov     w21, w0
165         mov     x20, x2
166 
167         puts    "Terminated by signal "
168         mov     w0, w21
169         bl      putdec
170         puts    ", no error, iterations="
171         ldr     x0, [x20, #ucontext_regs + 8 * 22]
172         bl      putdec
173         puts    ", signals="
174         ldr     x0, [x20, #ucontext_regs + 8 * 23]
175         bl      putdecn
176 
177         mov     x0, #0
178         mov     x8, #__NR_exit
179         svc     #0
180 endfunction
181 
182 // w0: signal number
183 // x1: sa_action
184 // w2: sa_flags
185 // Clobbers x0-x6,x8
186 function setsignal
187         str     x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
188 
189         mov     w4, w0
190         mov     x5, x1
191         mov     w6, w2
192 
193         add     x0, sp, #16
194         mov     x1, #sa_sz
195         bl      memclr
196 
197         mov     w0, w4
198         add     x1, sp, #16
199         str     w6, [x1, #sa_flags]
200         str     x5, [x1, #sa_handler]
201         mov     x2, #0
202         mov     x3, #sa_mask_sz
203         mov     x8, #__NR_rt_sigaction
204         svc     #0
205 
206         cbz     w0, 1f
207 
208         puts    "sigaction failure\n"
209         b       .Labort
210 
211 1:      ldr     x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
212         ret
213 endfunction
214 
215 // Main program entry point
216 .globl _start
217 function _start
218         mov     x23, #0         // signal count
219 
220         mov     w0, #SIGINT
221         adr     x1, terminate_handler
222         mov     w2, #SA_SIGINFO
223         bl      setsignal
224 
225         mov     w0, #SIGTERM
226         adr     x1, terminate_handler
227         mov     w2, #SA_SIGINFO
228         bl      setsignal
229 
230         mov     w0, #SIGUSR1
231         adr     x1, irritator_handler
232         mov     w2, #SA_SIGINFO
233         orr     w2, w2, #SA_NODEFER
234         bl      setsignal
235 
236         mov     w0, #SIGUSR2
237         adr     x1, tickle_handler
238         mov     w2, #SA_SIGINFO
239         orr     w2, w2, #SA_NODEFER
240         bl      setsignal
241 
242         // Sanity-check and report the vector length
243 
244         mov     x19, #128
245         cmp     x19, #128
246         b.lo    1f
247         cmp     x19, #2048
248         b.hi    1f
249         tst     x19, #(8 - 1)
250         b.eq    2f
251 
252 1:      puts    "Bad vector length: "
253         mov     x0, x19
254         bl      putdecn
255         b       .Labort
256 
257 2:      puts    "Vector length:\t"
258         mov     x0, x19
259         bl      putdec
260         puts    " bits\n"
261 
262         // Obtain our PID, to ensure test pattern uniqueness between processes
263 
264         mov     x8, #__NR_getpid
265         svc     #0
266         mov     x20, x0
267 
268         puts    "PID:\t"
269         mov     x0, x20
270         bl      putdecn
271 
272         mov     x22, #0         // generation number, increments per iteration
273 .Ltest_loop:
274 
275         mov     x21, #0         // Set up V-regs & shadow with test pattern
276 0:      mov     x0, x20
277         mov     x1, x21
278         and     x2, x22, #0xf
279         bl      setup_vreg
280         add     x21, x21, #1
281         cmp     x21, #NVR
282         b.lo    0b
283 
284 // Can't do this when SVE state is volatile across SVC:
285         mov     x8, #__NR_sched_yield   // Encourage preemption
286         svc     #0
287 
288         mov     x21, #0
289 0:      mov     x0, x21
290         bl      check_vreg
291         add     x21, x21, #1
292         cmp     x21, #NVR
293         b.lo    0b
294 
295         add     x22, x22, #1
296         b       .Ltest_loop
297 
298 .Labort:
299         mov     x0, #0
300         mov     x1, #SIGABRT
301         mov     x8, #__NR_kill
302         svc     #0
303 endfunction
304 
305 function barf
306         mov     x10, x0 // expected data
307         mov     x11, x1 // actual data
308         mov     x12, x2 // data size
309 
310         puts    "Mismatch: PID="
311         mov     x0, x20
312         bl      putdec
313         puts    ", iteration="
314         mov     x0, x22
315         bl      putdec
316         puts    ", reg="
317         mov     x0, x21
318         bl      putdecn
319         puts    "\tExpected ["
320         mov     x0, x10
321         mov     x1, x12
322         bl      dumphex
323         puts    "]\n\tGot      ["
324         mov     x0, x11
325         mov     x1, x12
326         bl      dumphex
327         puts    "]\n"
328 
329         mov     x8, #__NR_exit
330         mov     x1, #1
331         svc     #0
332 endfunction

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php