322 lines · plain
1// SPDX-License-Identifier: GPL-2.0-only2// Copyright (C) 2021-2 ARM Limited.3// Original author: Mark Brown <broonie@kernel.org>4//5// Scalable Matrix Extension ZT context switch test6// Repeatedly writes unique test patterns into ZT07// 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 sve15 16#define ZT_SZ 51217#define ZT_B (ZT_SZ / 8)18 19// Declare some storage space to shadow ZT register contents and a20// scratch buffer.21.pushsection .text22.data23.align 424ztref:25 .space ZT_B26scratch:27 .space ZT_B28.popsection29 30 31// Generate a test pattern for storage in ZT32// x0: pid33// x1: generation34 35// These values are used to construct a 32-bit pattern that is repeated in the36// scratch buffer as many times as will fit:37// bits 31:24 generation number (increments once per test_loop)38// bits 23: 8 pid39// bits 7: 0 32-bit lane index40 41function pattern42 mov w3, wzr43 bfi w3, w0, #8, #16 // PID44 bfi w3, w1, #24, #8 // Generation45 46 ldr x0, =scratch47 mov w1, #ZT_B / 448 490: str w3, [x0], #450 add w3, w3, #1 // Lane51 subs w1, w1, #152 b.ne 0b53 54 ret55endfunction56 57// Set up test pattern in a ZT horizontal vector58// x0: pid59// x1: generation60function setup_zt61 mov x4, x3062 63 bl pattern // Get pattern in scratch buffer64 ldr x0, =ztref65 ldr x1, =scratch66 mov x2, #ZT_B67 bl memcpy68 69 ldr x0, =ztref70 _ldr_zt 0 // load zt0 from pointer x071 72 ret x473endfunction74 75// Trivial memory compare: compare x2 bytes starting at address x0 with76// bytes starting at address x1.77// Returns only if all bytes match; otherwise, the program is aborted.78// Clobbers x0-x5.79function memcmp80 cbz x2, 2f81 82 stp x0, x1, [sp, #-0x20]!83 str x2, [sp, #0x10]84 85 mov x5, #0860: ldrb w3, [x0, x5]87 ldrb w4, [x1, x5]88 add x5, x5, #189 cmp w3, w490 b.ne 1f91 subs x2, x2, #192 b.ne 0b93 941: ldr x2, [sp, #0x10]95 ldp x0, x1, [sp], #0x2096 b.ne barf97 982: ret99endfunction100 101// Verify that a ZT vector matches its shadow in memory, else abort102// Clobbers x0-x3103function check_zt104 mov x3, x30105 106 ldr x0, =scratch // Poison scratch107 mov x1, #ZT_B108 bl memfill_ae109 110 ldr x0, =scratch111 _str_zt 0112 113 ldr x0, =ztref114 ldr x1, =scratch115 mov x2, #ZT_B116 mov x30, x3117 b memcmp118endfunction119 120// Any SME register modified here can cause corruption in the main121// thread -- but *only* the locations modified here.122function irritator_handler123 // Increment the irritation signal count (x23):124 ldr x0, [x2, #ucontext_regs + 8 * 23]125 add x0, x0, #1126 str x0, [x2, #ucontext_regs + 8 * 23]127 128 // Corrupt some random ZT data129#if 0130 adr x0, .text + (irritator_handler - .text) / 16 * 16131 movi v0.8b, #1132 movi v9.16b, #2133 movi v31.8b, #3134#endif135 136 ret137endfunction138 139function tickle_handler140 // Increment the signal count (x23):141 ldr x0, [x2, #ucontext_regs + 8 * 23]142 add x0, x0, #1143 str x0, [x2, #ucontext_regs + 8 * 23]144 145 ret146endfunction147 148function terminate_handler149 mov w21, w0150 mov x20, x2151 152 puts "Terminated by signal "153 mov w0, w21154 bl putdec155 puts ", no error, iterations="156 ldr x0, [x20, #ucontext_regs + 8 * 22]157 bl putdec158 puts ", signals="159 ldr x0, [x20, #ucontext_regs + 8 * 23]160 bl putdecn161 162 mov x0, #0163 mov x8, #__NR_exit164 svc #0165endfunction166 167// w0: signal number168// x1: sa_action169// w2: sa_flags170// Clobbers x0-x6,x8171function setsignal172 str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!173 174 mov w4, w0175 mov x5, x1176 mov w6, w2177 178 add x0, sp, #16179 mov x1, #sa_sz180 bl memclr181 182 mov w0, w4183 add x1, sp, #16184 str w6, [x1, #sa_flags]185 str x5, [x1, #sa_handler]186 mov x2, #0187 mov x3, #sa_mask_sz188 mov x8, #__NR_rt_sigaction189 svc #0190 191 cbz w0, 1f192 193 puts "sigaction failure\n"194 b .Labort195 1961: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)197 ret198endfunction199 200// Main program entry point201.globl _start202function _start203 mov x23, #0 // signal count204 205 mov w0, #SIGINT206 adr x1, terminate_handler207 mov w2, #SA_SIGINFO208 bl setsignal209 210 mov w0, #SIGTERM211 adr x1, terminate_handler212 mov w2, #SA_SIGINFO213 bl setsignal214 215 mov w0, #SIGUSR1216 adr x1, irritator_handler217 mov w2, #SA_SIGINFO218 orr w2, w2, #SA_NODEFER219 bl setsignal220 221 mov w0, #SIGUSR2222 adr x1, tickle_handler223 mov w2, #SA_SIGINFO224 orr w2, w2, #SA_NODEFER225 bl setsignal226 227 smstart_za228 229 // Obtain our PID, to ensure test pattern uniqueness between processes230 mov x8, #__NR_getpid231 svc #0232 mov x20, x0233 234 puts "PID:\t"235 mov x0, x20236 bl putdecn237 238 mov x22, #0 // generation number, increments per iteration239.Ltest_loop:240 mov x0, x20241 mov x1, x22242 bl setup_zt243 244 mov x8, #__NR_sched_yield // Encourage preemption245 svc #0246 247 mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=1,SM=0248 and x1, x0, #3249 cmp x1, #2250 b.ne svcr_barf251 252 bl check_zt253 254 add x22, x22, #1 // Everything still working255 b .Ltest_loop256 257.Labort:258 mov x0, #0259 mov x1, #SIGABRT260 mov x8, #__NR_kill261 svc #0262endfunction263 264function barf265// fpsimd.c acitivty log dump hack266// ldr w0, =0xdeadc0de267// mov w8, #__NR_exit268// svc #0269// end hack270 271 mrs x13, S3_3_C4_C2_2272 smstop273 mov x10, x0 // expected data274 mov x11, x1 // actual data275 mov x12, x2 // data size276 277 puts "Mismatch: PID="278 mov x0, x20279 bl putdec280 puts ", iteration="281 mov x0, x22282 bl putdec283 puts "\tExpected ["284 mov x0, x10285 mov x1, x12286 bl dumphex287 puts "]\n\tGot ["288 mov x0, x11289 mov x1, x12290 bl dumphex291 puts "]\n"292 puts "\tSVCR: "293 mov x0, x13294 bl putdecn295 296 mov x8, #__NR_getpid297 svc #0298// fpsimd.c acitivty log dump hack299// ldr w0, =0xdeadc0de300// mov w8, #__NR_exit301// svc #0302// ^ end of hack303 mov x1, #SIGABRT304 mov x8, #__NR_kill305 svc #0306// mov x8, #__NR_exit307// mov x1, #1308// svc #0309endfunction310 311function svcr_barf312 mov x10, x0313 314 puts "Bad SVCR: "315 mov x0, x10316 bl putdecn317 318 mov x8, #__NR_exit319 mov x1, #1320 svc #0321endfunction322