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 // Any SME register modified here can cause corruption in the main 121 // thread -- but *only* the locations modified here. 122 function 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 137 endfunction 138 139 function 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 146 endfunction 147 148 function 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 165 endfunction 166 167 // w0: signal number 168 // x1: sa_action 169 // w2: sa_flags 170 // Clobbers x0-x6,x8 171 function 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 196 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16) 197 ret 198 endfunction 199 200 // Main program entry point 201 .globl _start 202 function _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 262 endfunction 263 264 function 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 309 endfunction 310 311 function 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 321 endfunction
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.