za-test.S 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Copyright (C) 2021 ARM Limited.
  3. // Original author: Mark Brown <broonie@kernel.org>
  4. //
  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.
  8. //
  9. // for x in `seq 1 NR_CPUS`; do sve-test & pids=$pids\ $! ; done
  10. // (leave it running for as long as you want...)
  11. // kill $pids
  12. #include <asm/unistd.h>
  13. #include "assembler.h"
  14. #include "asm-offsets.h"
  15. #include "sme-inst.h"
  16. .arch_extension sve
  17. #define MAXVL 2048
  18. #define MAXVL_B (MAXVL / 8)
  19. // Declare some storage space to shadow ZA register contents and a
  20. // scratch buffer for a vector.
  21. .pushsection .text
  22. .data
  23. .align 4
  24. zaref:
  25. .space MAXVL_B * MAXVL_B
  26. scratch:
  27. .space MAXVL_B
  28. .popsection
  29. // Trivial memory copy: copy x2 bytes, starting at address x1, to address x0.
  30. // Clobbers x0-x3
  31. function memcpy
  32. cmp x2, #0
  33. b.eq 1f
  34. 0: ldrb w3, [x1], #1
  35. strb w3, [x0], #1
  36. subs x2, x2, #1
  37. b.ne 0b
  38. 1: ret
  39. endfunction
  40. // Generate a test pattern for storage in ZA
  41. // x0: pid
  42. // x1: row in ZA
  43. // x2: generation
  44. // These values are used to constuct a 32-bit pattern that is repeated in the
  45. // scratch buffer as many times as will fit:
  46. // bits 31:28 generation number (increments once per test_loop)
  47. // bits 27:16 pid
  48. // bits 15: 8 row number
  49. // bits 7: 0 32-bit lane index
  50. function pattern
  51. mov w3, wzr
  52. bfi w3, w0, #16, #12 // PID
  53. bfi w3, w1, #8, #8 // Row
  54. bfi w3, w2, #28, #4 // Generation
  55. ldr x0, =scratch
  56. mov w1, #MAXVL_B / 4
  57. 0: str w3, [x0], #4
  58. add w3, w3, #1 // Lane
  59. subs w1, w1, #1
  60. b.ne 0b
  61. ret
  62. endfunction
  63. // Get the address of shadow data for ZA horizontal vector xn
  64. .macro _adrza xd, xn, nrtmp
  65. ldr \xd, =zaref
  66. rdsvl \nrtmp, 1
  67. madd \xd, x\nrtmp, \xn, \xd
  68. .endm
  69. // Set up test pattern in a ZA horizontal vector
  70. // x0: pid
  71. // x1: row number
  72. // x2: generation
  73. function setup_za
  74. mov x4, x30
  75. mov x12, x1 // Use x12 for vector select
  76. bl pattern // Get pattern in scratch buffer
  77. _adrza x0, x12, 2 // Shadow buffer pointer to x0 and x5
  78. mov x5, x0
  79. ldr x1, =scratch
  80. bl memcpy // length set up in x2 by _adrza
  81. _ldr_za 12, 5 // load vector w12 from pointer x5
  82. ret x4
  83. endfunction
  84. // Trivial memory compare: compare x2 bytes starting at address x0 with
  85. // bytes starting at address x1.
  86. // Returns only if all bytes match; otherwise, the program is aborted.
  87. // Clobbers x0-x5.
  88. function memcmp
  89. cbz x2, 2f
  90. stp x0, x1, [sp, #-0x20]!
  91. str x2, [sp, #0x10]
  92. mov x5, #0
  93. 0: ldrb w3, [x0, x5]
  94. ldrb w4, [x1, x5]
  95. add x5, x5, #1
  96. cmp w3, w4
  97. b.ne 1f
  98. subs x2, x2, #1
  99. b.ne 0b
  100. 1: ldr x2, [sp, #0x10]
  101. ldp x0, x1, [sp], #0x20
  102. b.ne barf
  103. 2: ret
  104. endfunction
  105. // Verify that a ZA vector matches its shadow in memory, else abort
  106. // x0: row number
  107. // Clobbers x0-x7 and x12.
  108. function check_za
  109. mov x3, x30
  110. mov x12, x0
  111. _adrza x5, x0, 6 // pointer to expected value in x5
  112. mov x4, x0
  113. ldr x7, =scratch // x7 is scratch
  114. mov x0, x7 // Poison scratch
  115. mov x1, x6
  116. bl memfill_ae
  117. _str_za 12, 7 // save vector w12 to pointer x7
  118. mov x0, x5
  119. mov x1, x7
  120. mov x2, x6
  121. mov x30, x3
  122. b memcmp
  123. endfunction
  124. // Any SME register modified here can cause corruption in the main
  125. // thread -- but *only* the locations modified here.
  126. function irritator_handler
  127. // Increment the irritation signal count (x23):
  128. ldr x0, [x2, #ucontext_regs + 8 * 23]
  129. add x0, x0, #1
  130. str x0, [x2, #ucontext_regs + 8 * 23]
  131. // Corrupt some random ZA data
  132. #if 0
  133. adr x0, .text + (irritator_handler - .text) / 16 * 16
  134. movi v0.8b, #1
  135. movi v9.16b, #2
  136. movi v31.8b, #3
  137. #endif
  138. ret
  139. endfunction
  140. function tickle_handler
  141. // Increment the signal count (x23):
  142. ldr x0, [x2, #ucontext_regs + 8 * 23]
  143. add x0, x0, #1
  144. str x0, [x2, #ucontext_regs + 8 * 23]
  145. ret
  146. endfunction
  147. function terminate_handler
  148. mov w21, w0
  149. mov x20, x2
  150. puts "Terminated by signal "
  151. mov w0, w21
  152. bl putdec
  153. puts ", no error, iterations="
  154. ldr x0, [x20, #ucontext_regs + 8 * 22]
  155. bl putdec
  156. puts ", signals="
  157. ldr x0, [x20, #ucontext_regs + 8 * 23]
  158. bl putdecn
  159. mov x0, #0
  160. mov x8, #__NR_exit
  161. svc #0
  162. endfunction
  163. // w0: signal number
  164. // x1: sa_action
  165. // w2: sa_flags
  166. // Clobbers x0-x6,x8
  167. function setsignal
  168. str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
  169. mov w4, w0
  170. mov x5, x1
  171. mov w6, w2
  172. add x0, sp, #16
  173. mov x1, #sa_sz
  174. bl memclr
  175. mov w0, w4
  176. add x1, sp, #16
  177. str w6, [x1, #sa_flags]
  178. str x5, [x1, #sa_handler]
  179. mov x2, #0
  180. mov x3, #sa_mask_sz
  181. mov x8, #__NR_rt_sigaction
  182. svc #0
  183. cbz w0, 1f
  184. puts "sigaction failure\n"
  185. b .Labort
  186. 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
  187. ret
  188. endfunction
  189. // Main program entry point
  190. .globl _start
  191. function _start
  192. mov x23, #0 // signal count
  193. mov w0, #SIGINT
  194. adr x1, terminate_handler
  195. mov w2, #SA_SIGINFO
  196. bl setsignal
  197. mov w0, #SIGTERM
  198. adr x1, terminate_handler
  199. mov w2, #SA_SIGINFO
  200. bl setsignal
  201. mov w0, #SIGUSR1
  202. adr x1, irritator_handler
  203. mov w2, #SA_SIGINFO
  204. orr w2, w2, #SA_NODEFER
  205. bl setsignal
  206. mov w0, #SIGUSR2
  207. adr x1, tickle_handler
  208. mov w2, #SA_SIGINFO
  209. orr w2, w2, #SA_NODEFER
  210. bl setsignal
  211. puts "Streaming mode "
  212. smstart_za
  213. // Sanity-check and report the vector length
  214. rdsvl 19, 8
  215. cmp x19, #128
  216. b.lo 1f
  217. cmp x19, #2048
  218. b.hi 1f
  219. tst x19, #(8 - 1)
  220. b.eq 2f
  221. 1: puts "bad vector length: "
  222. mov x0, x19
  223. bl putdecn
  224. b .Labort
  225. 2: puts "vector length:\t"
  226. mov x0, x19
  227. bl putdec
  228. puts " bits\n"
  229. // Obtain our PID, to ensure test pattern uniqueness between processes
  230. mov x8, #__NR_getpid
  231. svc #0
  232. mov x20, x0
  233. puts "PID:\t"
  234. mov x0, x20
  235. bl putdecn
  236. mov x22, #0 // generation number, increments per iteration
  237. .Ltest_loop:
  238. rdsvl 0, 8
  239. cmp x0, x19
  240. b.ne vl_barf
  241. rdsvl 21, 1 // Set up ZA & shadow with test pattern
  242. 0: mov x0, x20
  243. sub x1, x21, #1
  244. mov x2, x22
  245. bl setup_za
  246. subs x21, x21, #1
  247. b.ne 0b
  248. mov x8, #__NR_sched_yield // encourage preemption
  249. 1:
  250. svc #0
  251. mrs x0, S3_3_C4_C2_2 // SVCR should have ZA=1,SM=0
  252. and x1, x0, #3
  253. cmp x1, #2
  254. b.ne svcr_barf
  255. rdsvl 21, 1 // Verify that the data made it through
  256. rdsvl 24, 1 // Verify that the data made it through
  257. 0: sub x0, x24, x21
  258. bl check_za
  259. subs x21, x21, #1
  260. bne 0b
  261. add x22, x22, #1 // Everything still working
  262. b .Ltest_loop
  263. .Labort:
  264. mov x0, #0
  265. mov x1, #SIGABRT
  266. mov x8, #__NR_kill
  267. svc #0
  268. endfunction
  269. function barf
  270. // fpsimd.c acitivty log dump hack
  271. // ldr w0, =0xdeadc0de
  272. // mov w8, #__NR_exit
  273. // svc #0
  274. // end hack
  275. mrs x13, S3_3_C4_C2_2
  276. smstop
  277. mov x10, x0 // expected data
  278. mov x11, x1 // actual data
  279. mov x12, x2 // data size
  280. puts "Mismatch: PID="
  281. mov x0, x20
  282. bl putdec
  283. puts ", iteration="
  284. mov x0, x22
  285. bl putdec
  286. puts ", row="
  287. mov x0, x21
  288. bl putdecn
  289. puts "\tExpected ["
  290. mov x0, x10
  291. mov x1, x12
  292. bl dumphex
  293. puts "]\n\tGot ["
  294. mov x0, x11
  295. mov x1, x12
  296. bl dumphex
  297. puts "]\n"
  298. puts "\tSVCR: "
  299. mov x0, x13
  300. bl putdecn
  301. mov x8, #__NR_getpid
  302. svc #0
  303. // fpsimd.c acitivty log dump hack
  304. // ldr w0, =0xdeadc0de
  305. // mov w8, #__NR_exit
  306. // svc #0
  307. // ^ end of hack
  308. mov x1, #SIGABRT
  309. mov x8, #__NR_kill
  310. svc #0
  311. // mov x8, #__NR_exit
  312. // mov x1, #1
  313. // svc #0
  314. endfunction
  315. function vl_barf
  316. mov x10, x0
  317. puts "Bad active VL: "
  318. mov x0, x10
  319. bl putdecn
  320. mov x8, #__NR_exit
  321. mov x1, #1
  322. svc #0
  323. endfunction
  324. function svcr_barf
  325. mov x10, x0
  326. puts "Bad SVCR: "
  327. mov x0, x10
  328. bl putdecn
  329. mov x8, #__NR_exit
  330. mov x1, #1
  331. svc #0
  332. endfunction