1 | // SPDX-License-Identifier: GPL-2.0-only |
---|---|
2 | /* |
3 | * Copyright (C) 2022 ARM Limited. |
4 | */ |
5 | |
6 | #include <errno.h> |
7 | #include <signal.h> |
8 | #include <stdbool.h> |
9 | #include <stddef.h> |
10 | #include <stdio.h> |
11 | #include <stdlib.h> |
12 | #include <string.h> |
13 | #include <unistd.h> |
14 | #include <sys/auxv.h> |
15 | #include <sys/prctl.h> |
16 | #include <asm/hwcap.h> |
17 | #include <asm/sigcontext.h> |
18 | #include <asm/unistd.h> |
19 | |
20 | #include "../../kselftest.h" |
21 | |
22 | #define TESTS_PER_HWCAP 3 |
23 | |
24 | /* |
25 | * Function expected to generate exception when the feature is not |
26 | * supported and return when it is supported. If the specific exception |
27 | * is generated then the handler must be able to skip over the |
28 | * instruction safely. |
29 | * |
30 | * Note that it is expected that for many architecture extensions |
31 | * there are no specific traps due to no architecture state being |
32 | * added so we may not fault if running on a kernel which doesn't know |
33 | * to add the hwcap. |
34 | */ |
35 | typedef void (*sig_fn)(void); |
36 | |
37 | static void aes_sigill(void) |
38 | { |
39 | /* AESE V0.16B, V0.16B */ |
40 | asm volatile(".inst 0x4e284800": : : ); |
41 | } |
42 | |
43 | static void atomics_sigill(void) |
44 | { |
45 | /* STADD W0, [SP] */ |
46 | asm volatile(".inst 0xb82003ff": : : ); |
47 | } |
48 | |
49 | static void cmpbr_sigill(void) |
50 | { |
51 | /* Not implemented, too complicated and unreliable anyway */ |
52 | } |
53 | |
54 | |
55 | static void crc32_sigill(void) |
56 | { |
57 | /* CRC32W W0, W0, W1 */ |
58 | asm volatile(".inst 0x1ac14800": : : ); |
59 | } |
60 | |
61 | static void cssc_sigill(void) |
62 | { |
63 | /* CNT x0, x0 */ |
64 | asm volatile(".inst 0xdac01c00": : : "x0"); |
65 | } |
66 | |
67 | static void f8cvt_sigill(void) |
68 | { |
69 | /* FSCALE V0.4H, V0.4H, V0.4H */ |
70 | asm volatile(".inst 0x2ec03c00"); |
71 | } |
72 | |
73 | static void f8dp2_sigill(void) |
74 | { |
75 | /* FDOT V0.4H, V0.4H, V0.5H */ |
76 | asm volatile(".inst 0xe40fc00"); |
77 | } |
78 | |
79 | static void f8dp4_sigill(void) |
80 | { |
81 | /* FDOT V0.2S, V0.2S, V0.2S */ |
82 | asm volatile(".inst 0xe00fc00"); |
83 | } |
84 | |
85 | static void f8fma_sigill(void) |
86 | { |
87 | /* FMLALB V0.8H, V0.16B, V0.16B */ |
88 | asm volatile(".inst 0xec0fc00"); |
89 | } |
90 | |
91 | static void f8mm4_sigill(void) |
92 | { |
93 | /* FMMLA V0.4SH, V0.16B, V0.16B */ |
94 | asm volatile(".inst 0x6e00ec00"); |
95 | } |
96 | |
97 | static void f8mm8_sigill(void) |
98 | { |
99 | /* FMMLA V0.4S, V0.16B, V0.16B */ |
100 | asm volatile(".inst 0x6e80ec00"); |
101 | } |
102 | |
103 | static void faminmax_sigill(void) |
104 | { |
105 | /* FAMIN V0.4H, V0.4H, V0.4H */ |
106 | asm volatile(".inst 0x2ec01c00"); |
107 | } |
108 | |
109 | static void fp_sigill(void) |
110 | { |
111 | asm volatile("fmov s0, #1"); |
112 | } |
113 | |
114 | static void fpmr_sigill(void) |
115 | { |
116 | asm volatile("mrs x0, S3_3_C4_C4_2": : : "x0"); |
117 | } |
118 | |
119 | static void fprcvt_sigill(void) |
120 | { |
121 | /* FCVTAS S0, H0 */ |
122 | asm volatile(".inst 0x1efa0000"); |
123 | } |
124 | |
125 | static void gcs_sigill(void) |
126 | { |
127 | unsigned long *gcspr; |
128 | |
129 | asm volatile( |
130 | "mrs %0, S3_3_C2_C5_1" |
131 | : "=r"(gcspr) |
132 | : |
133 | : "cc"); |
134 | } |
135 | |
136 | static void ilrcpc_sigill(void) |
137 | { |
138 | /* LDAPUR W0, [SP, #8] */ |
139 | asm volatile(".inst 0x994083e0": : : ); |
140 | } |
141 | |
142 | static void jscvt_sigill(void) |
143 | { |
144 | /* FJCVTZS W0, D0 */ |
145 | asm volatile(".inst 0x1e7e0000": : : ); |
146 | } |
147 | |
148 | static void lrcpc_sigill(void) |
149 | { |
150 | /* LDAPR W0, [SP, #0] */ |
151 | asm volatile(".inst 0xb8bfc3e0": : : ); |
152 | } |
153 | |
154 | static void lse128_sigill(void) |
155 | { |
156 | u64 __attribute__ ((aligned (16))) mem[2] = { 10, 20 }; |
157 | register u64 *memp asm ("x0") = mem; |
158 | register u64 val0 asm ("x1") = 5; |
159 | register u64 val1 asm ("x2") = 4; |
160 | |
161 | /* SWPP X1, X2, [X0] */ |
162 | asm volatile(".inst 0x19228001" |
163 | : "+r"(memp), "+r"(val0), "+r"(val1) |
164 | : |
165 | : "cc", "memory"); |
166 | } |
167 | |
168 | static void lut_sigill(void) |
169 | { |
170 | /* LUTI2 V0.16B, { V0.16B }, V[0] */ |
171 | asm volatile(".inst 0x4e801000"); |
172 | } |
173 | |
174 | static void mops_sigill(void) |
175 | { |
176 | char dst[1], src[1]; |
177 | register char *dstp asm ("x0") = dst; |
178 | register char *srcp asm ("x1") = src; |
179 | register long size asm ("x2") = 1; |
180 | |
181 | /* CPYP [x0]!, [x1]!, x2! */ |
182 | asm volatile(".inst 0x1d010440" |
183 | : "+r"(dstp), "+r"(srcp), "+r"(size) |
184 | : |
185 | : "cc", "memory"); |
186 | } |
187 | |
188 | static void pmull_sigill(void) |
189 | { |
190 | /* PMULL V0.1Q, V0.1D, V0.1D */ |
191 | asm volatile(".inst 0x0ee0e000": : : ); |
192 | } |
193 | |
194 | static void poe_sigill(void) |
195 | { |
196 | /* mrs x0, POR_EL0 */ |
197 | asm volatile("mrs x0, S3_3_C10_C2_4": : : "x0"); |
198 | } |
199 | |
200 | static void rng_sigill(void) |
201 | { |
202 | asm volatile("mrs x0, S3_3_C2_C4_0": : : "x0"); |
203 | } |
204 | |
205 | static void sha1_sigill(void) |
206 | { |
207 | /* SHA1H S0, S0 */ |
208 | asm volatile(".inst 0x5e280800": : : ); |
209 | } |
210 | |
211 | static void sha2_sigill(void) |
212 | { |
213 | /* SHA256H Q0, Q0, V0.4S */ |
214 | asm volatile(".inst 0x5e004000": : : ); |
215 | } |
216 | |
217 | static void sha512_sigill(void) |
218 | { |
219 | /* SHA512H Q0, Q0, V0.2D */ |
220 | asm volatile(".inst 0xce608000": : : ); |
221 | } |
222 | |
223 | static void sme_sigill(void) |
224 | { |
225 | /* RDSVL x0, #0 */ |
226 | asm volatile(".inst 0x04bf5800": : : "x0"); |
227 | } |
228 | |
229 | static void sme2_sigill(void) |
230 | { |
231 | /* SMSTART ZA */ |
232 | asm volatile("msr S0_3_C4_C5_3, xzr": : : ); |
233 | |
234 | /* ZERO ZT0 */ |
235 | asm volatile(".inst 0xc0480001": : : ); |
236 | |
237 | /* SMSTOP */ |
238 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
239 | } |
240 | |
241 | static void sme2p1_sigill(void) |
242 | { |
243 | /* SMSTART SM */ |
244 | asm volatile("msr S0_3_C4_C3_3, xzr": : : ); |
245 | |
246 | /* BFCLAMP { Z0.H - Z1.H }, Z0.H, Z0.H */ |
247 | asm volatile(".inst 0xc120C000": : : ); |
248 | |
249 | /* SMSTOP */ |
250 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
251 | } |
252 | |
253 | static void sme2p2_sigill(void) |
254 | { |
255 | /* SMSTART SM */ |
256 | asm volatile("msr S0_3_C4_C3_3, xzr": : : ); |
257 | |
258 | /* UXTB Z0.D, P0/Z, Z0.D */ |
259 | asm volatile(".inst 0x4c1a000": : : ); |
260 | |
261 | /* SMSTOP */ |
262 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
263 | } |
264 | |
265 | static void sme_aes_sigill(void) |
266 | { |
267 | /* SMSTART SM */ |
268 | asm volatile("msr S0_3_C4_C3_3, xzr": : : ); |
269 | |
270 | /* AESD z0.b, z0.b, z0.b */ |
271 | asm volatile(".inst 0x4522e400": : : "z0"); |
272 | |
273 | /* SMSTOP */ |
274 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
275 | } |
276 | |
277 | static void sme_sbitperm_sigill(void) |
278 | { |
279 | /* SMSTART SM */ |
280 | asm volatile("msr S0_3_C4_C3_3, xzr": : : ); |
281 | |
282 | /* BDEP Z0.B, Z0.B, Z0.B */ |
283 | asm volatile(".inst 0x4500b400": : : "z0"); |
284 | |
285 | /* SMSTOP */ |
286 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
287 | } |
288 | |
289 | static void smei16i32_sigill(void) |
290 | { |
291 | /* SMSTART */ |
292 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
293 | |
294 | /* SMOPA ZA0.S, P0/M, P0/M, Z0.B, Z0.B */ |
295 | asm volatile(".inst 0xa0800000": : : ); |
296 | |
297 | /* SMSTOP */ |
298 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
299 | } |
300 | |
301 | static void smebi32i32_sigill(void) |
302 | { |
303 | /* SMSTART */ |
304 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
305 | |
306 | /* BMOPA ZA0.S, P0/M, P0/M, Z0.B, Z0.B */ |
307 | asm volatile(".inst 0x80800008": : : ); |
308 | |
309 | /* SMSTOP */ |
310 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
311 | } |
312 | |
313 | static void smeb16b16_sigill(void) |
314 | { |
315 | /* SMSTART */ |
316 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
317 | |
318 | /* BFADD ZA.H[W0, 0], {Z0.H-Z1.H} */ |
319 | asm volatile(".inst 0xC1E41C00": : : ); |
320 | |
321 | /* SMSTOP */ |
322 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
323 | } |
324 | |
325 | static void smef16f16_sigill(void) |
326 | { |
327 | /* SMSTART */ |
328 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
329 | |
330 | /* FADD ZA.H[W0, 0], { Z0.H-Z1.H } */ |
331 | asm volatile(".inst 0xc1a41C00": : : ); |
332 | |
333 | /* SMSTOP */ |
334 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
335 | } |
336 | |
337 | static void smef8f16_sigill(void) |
338 | { |
339 | /* SMSTART */ |
340 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
341 | |
342 | /* FDOT ZA.H[W0, 0], Z0.B-Z1.B, Z0.B-Z1.B */ |
343 | asm volatile(".inst 0xc1a01020": : : ); |
344 | |
345 | /* SMSTOP */ |
346 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
347 | } |
348 | |
349 | static void smef8f32_sigill(void) |
350 | { |
351 | /* SMSTART */ |
352 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
353 | |
354 | /* FDOT ZA.S[W0, 0], { Z0.B-Z1.B }, Z0.B[0] */ |
355 | asm volatile(".inst 0xc1500038": : : ); |
356 | |
357 | /* SMSTOP */ |
358 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
359 | } |
360 | |
361 | static void smelutv2_sigill(void) |
362 | { |
363 | /* SMSTART */ |
364 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
365 | |
366 | /* LUTI4 { Z0.B-Z3.B }, ZT0, { Z0-Z1 } */ |
367 | asm volatile(".inst 0xc08b0000": : : ); |
368 | |
369 | /* SMSTOP */ |
370 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
371 | } |
372 | |
373 | static void smesf8dp2_sigill(void) |
374 | { |
375 | /* SMSTART */ |
376 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
377 | |
378 | /* FDOT Z0.H, Z0.B, Z0.B[0] */ |
379 | asm volatile(".inst 0x64204400": : : ); |
380 | |
381 | /* SMSTOP */ |
382 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
383 | } |
384 | |
385 | static void smesf8dp4_sigill(void) |
386 | { |
387 | /* SMSTART */ |
388 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
389 | |
390 | /* FDOT Z0.S, Z0.B, Z0.B[0] */ |
391 | asm volatile(".inst 0xc1a41C00": : : ); |
392 | |
393 | /* SMSTOP */ |
394 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
395 | } |
396 | |
397 | static void smesf8fma_sigill(void) |
398 | { |
399 | /* SMSTART */ |
400 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
401 | |
402 | /* FMLALB Z0.8H, Z0.B, Z0.B */ |
403 | asm volatile(".inst 0x64205000"); |
404 | |
405 | /* SMSTOP */ |
406 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
407 | } |
408 | |
409 | static void smesfexpa_sigill(void) |
410 | { |
411 | /* SMSTART */ |
412 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
413 | |
414 | /* FEXPA Z0.D, Z0.D */ |
415 | asm volatile(".inst 0x04e0b800"); |
416 | |
417 | /* SMSTOP */ |
418 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
419 | } |
420 | |
421 | static void smesmop4_sigill(void) |
422 | { |
423 | /* SMSTART */ |
424 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
425 | |
426 | /* SMOP4A ZA0.S, Z0.B, { Z0.B - Z1.B } */ |
427 | asm volatile(".inst 0x80108000"); |
428 | |
429 | /* SMSTOP */ |
430 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
431 | } |
432 | |
433 | static void smestmop_sigill(void) |
434 | { |
435 | /* SMSTART */ |
436 | asm volatile("msr S0_3_C4_C7_3, xzr": : : ); |
437 | |
438 | /* STMOPA ZA0.S, { Z0.H - Z1.H }, Z0.H, Z20[0] */ |
439 | asm volatile(".inst 0x80408008"); |
440 | |
441 | /* SMSTOP */ |
442 | asm volatile("msr S0_3_C4_C6_3, xzr": : : ); |
443 | } |
444 | |
445 | static void sve_sigill(void) |
446 | { |
447 | /* RDVL x0, #0 */ |
448 | asm volatile(".inst 0x04bf5000": : : "x0"); |
449 | } |
450 | |
451 | static void sve2_sigill(void) |
452 | { |
453 | /* SQABS Z0.b, P0/M, Z0.B */ |
454 | asm volatile(".inst 0x4408A000": : : "z0"); |
455 | } |
456 | |
457 | static void sve2p1_sigill(void) |
458 | { |
459 | /* BFADD Z0.H, Z0.H, Z0.H */ |
460 | asm volatile(".inst 0x65000000": : : "z0"); |
461 | } |
462 | |
463 | static void sve2p2_sigill(void) |
464 | { |
465 | /* NOT Z0.D, P0/Z, Z0.D */ |
466 | asm volatile(".inst 0x4cea000": : : "z0"); |
467 | } |
468 | |
469 | static void sveaes_sigill(void) |
470 | { |
471 | /* AESD z0.b, z0.b, z0.b */ |
472 | asm volatile(".inst 0x4522e400": : : "z0"); |
473 | } |
474 | |
475 | static void sveaes2_sigill(void) |
476 | { |
477 | /* AESD {Z0.B - Z1.B }, { Z0.B - Z1.B }, Z0.Q */ |
478 | asm volatile(".inst 0x4522ec00": : : "z0"); |
479 | } |
480 | |
481 | static void sveb16b16_sigill(void) |
482 | { |
483 | /* BFADD Z0.H, Z0.H, Z0.H */ |
484 | asm volatile(".inst 0x65000000": : : ); |
485 | } |
486 | |
487 | static void svebfscale_sigill(void) |
488 | { |
489 | /* BFSCALE Z0.H, P0/M, Z0.H, Z0.H */ |
490 | asm volatile(".inst 0x65098000": : : "z0"); |
491 | } |
492 | |
493 | static void svef16mm_sigill(void) |
494 | { |
495 | /* FMMLA Z0.S, Z0.H, Z0.H */ |
496 | asm volatile(".inst 0x6420e400"); |
497 | } |
498 | |
499 | static void svepmull_sigill(void) |
500 | { |
501 | /* PMULLB Z0.Q, Z0.D, Z0.D */ |
502 | asm volatile(".inst 0x45006800": : : "z0"); |
503 | } |
504 | |
505 | static void svebitperm_sigill(void) |
506 | { |
507 | /* BDEP Z0.B, Z0.B, Z0.B */ |
508 | asm volatile(".inst 0x4500b400": : : "z0"); |
509 | } |
510 | |
511 | static void svesha3_sigill(void) |
512 | { |
513 | /* EOR3 Z0.D, Z0.D, Z0.D, Z0.D */ |
514 | asm volatile(".inst 0x4203800": : : "z0"); |
515 | } |
516 | |
517 | static void sveeltperm_sigill(void) |
518 | { |
519 | /* COMPACT Z0.B, P0, Z0.B */ |
520 | asm volatile(".inst 0x5218000": : : "x0"); |
521 | } |
522 | |
523 | static void svesm4_sigill(void) |
524 | { |
525 | /* SM4E Z0.S, Z0.S, Z0.S */ |
526 | asm volatile(".inst 0x4523e000": : : "z0"); |
527 | } |
528 | |
529 | static void svei8mm_sigill(void) |
530 | { |
531 | /* USDOT Z0.S, Z0.B, Z0.B[0] */ |
532 | asm volatile(".inst 0x44a01800": : : "z0"); |
533 | } |
534 | |
535 | static void svef32mm_sigill(void) |
536 | { |
537 | /* FMMLA Z0.S, Z0.S, Z0.S */ |
538 | asm volatile(".inst 0x64a0e400": : : "z0"); |
539 | } |
540 | |
541 | static void svef64mm_sigill(void) |
542 | { |
543 | /* FMMLA Z0.D, Z0.D, Z0.D */ |
544 | asm volatile(".inst 0x64e0e400": : : "z0"); |
545 | } |
546 | |
547 | static void svebf16_sigill(void) |
548 | { |
549 | /* BFCVT Z0.H, P0/M, Z0.S */ |
550 | asm volatile(".inst 0x658aa000": : : "z0"); |
551 | } |
552 | |
553 | static void hbc_sigill(void) |
554 | { |
555 | /* BC.EQ +4 */ |
556 | asm volatile("cmp xzr, xzr\n" |
557 | ".inst 0x54000030": : : "cc"); |
558 | } |
559 | |
560 | static void uscat_sigbus(void) |
561 | { |
562 | /* unaligned atomic access */ |
563 | asm volatile("ADD x1, sp, #2": : : ); |
564 | /* STADD W0, [X1] */ |
565 | asm volatile(".inst 0xb820003f": : : ); |
566 | } |
567 | |
568 | static void lrcpc3_sigill(void) |
569 | { |
570 | int data[2] = { 1, 2 }; |
571 | |
572 | register int *src asm ("x0") = data; |
573 | register int data0 asm ("w2") = 0; |
574 | register int data1 asm ("w3") = 0; |
575 | |
576 | /* LDIAPP w2, w3, [x0] */ |
577 | asm volatile(".inst 0x99431802" |
578 | : "=r"(data0), "=r"(data1) : "r"(src) :); |
579 | } |
580 | |
581 | static const struct hwcap_data { |
582 | const char *name; |
583 | unsigned long at_hwcap; |
584 | unsigned long hwcap_bit; |
585 | const char *cpuinfo; |
586 | sig_fn sigill_fn; |
587 | bool sigill_reliable; |
588 | sig_fn sigbus_fn; |
589 | bool sigbus_reliable; |
590 | } hwcaps[] = { |
591 | { |
592 | .name = "AES", |
593 | .at_hwcap = AT_HWCAP, |
594 | .hwcap_bit = HWCAP_AES, |
595 | .cpuinfo = "aes", |
596 | .sigill_fn = aes_sigill, |
597 | }, |
598 | { |
599 | .name = "CMPBR", |
600 | .at_hwcap = AT_HWCAP, |
601 | .hwcap_bit = HWCAP_CMPBR, |
602 | .cpuinfo = "cmpbr", |
603 | .sigill_fn = cmpbr_sigill, |
604 | }, |
605 | { |
606 | .name = "CRC32", |
607 | .at_hwcap = AT_HWCAP, |
608 | .hwcap_bit = HWCAP_CRC32, |
609 | .cpuinfo = "crc32", |
610 | .sigill_fn = crc32_sigill, |
611 | }, |
612 | { |
613 | .name = "CSSC", |
614 | .at_hwcap = AT_HWCAP2, |
615 | .hwcap_bit = HWCAP2_CSSC, |
616 | .cpuinfo = "cssc", |
617 | .sigill_fn = cssc_sigill, |
618 | }, |
619 | { |
620 | .name = "F8CVT", |
621 | .at_hwcap = AT_HWCAP2, |
622 | .hwcap_bit = HWCAP2_F8CVT, |
623 | .cpuinfo = "f8cvt", |
624 | .sigill_fn = f8cvt_sigill, |
625 | }, |
626 | { |
627 | .name = "F8DP4", |
628 | .at_hwcap = AT_HWCAP2, |
629 | .hwcap_bit = HWCAP2_F8DP4, |
630 | .cpuinfo = "f8dp4", |
631 | .sigill_fn = f8dp4_sigill, |
632 | }, |
633 | { |
634 | .name = "F8DP2", |
635 | .at_hwcap = AT_HWCAP2, |
636 | .hwcap_bit = HWCAP2_F8DP2, |
637 | .cpuinfo = "f8dp2", |
638 | .sigill_fn = f8dp2_sigill, |
639 | }, |
640 | { |
641 | .name = "F8E5M2", |
642 | .at_hwcap = AT_HWCAP2, |
643 | .hwcap_bit = HWCAP2_F8E5M2, |
644 | .cpuinfo = "f8e5m2", |
645 | }, |
646 | { |
647 | .name = "F8E4M3", |
648 | .at_hwcap = AT_HWCAP2, |
649 | .hwcap_bit = HWCAP2_F8E4M3, |
650 | .cpuinfo = "f8e4m3", |
651 | }, |
652 | { |
653 | .name = "F8FMA", |
654 | .at_hwcap = AT_HWCAP2, |
655 | .hwcap_bit = HWCAP2_F8FMA, |
656 | .cpuinfo = "f8fma", |
657 | .sigill_fn = f8fma_sigill, |
658 | }, |
659 | { |
660 | .name = "F8MM8", |
661 | .at_hwcap = AT_HWCAP, |
662 | .hwcap_bit = HWCAP_F8MM8, |
663 | .cpuinfo = "f8mm8", |
664 | .sigill_fn = f8mm8_sigill, |
665 | }, |
666 | { |
667 | .name = "F8MM4", |
668 | .at_hwcap = AT_HWCAP, |
669 | .hwcap_bit = HWCAP_F8MM4, |
670 | .cpuinfo = "f8mm4", |
671 | .sigill_fn = f8mm4_sigill, |
672 | }, |
673 | { |
674 | .name = "FAMINMAX", |
675 | .at_hwcap = AT_HWCAP2, |
676 | .hwcap_bit = HWCAP2_FAMINMAX, |
677 | .cpuinfo = "faminmax", |
678 | .sigill_fn = faminmax_sigill, |
679 | }, |
680 | { |
681 | .name = "FP", |
682 | .at_hwcap = AT_HWCAP, |
683 | .hwcap_bit = HWCAP_FP, |
684 | .cpuinfo = "fp", |
685 | .sigill_fn = fp_sigill, |
686 | }, |
687 | { |
688 | .name = "FPMR", |
689 | .at_hwcap = AT_HWCAP2, |
690 | .hwcap_bit = HWCAP2_FPMR, |
691 | .cpuinfo = "fpmr", |
692 | .sigill_fn = fpmr_sigill, |
693 | .sigill_reliable = true, |
694 | }, |
695 | { |
696 | .name = "FPRCVT", |
697 | .at_hwcap = AT_HWCAP, |
698 | .hwcap_bit = HWCAP_FPRCVT, |
699 | .cpuinfo = "fprcvt", |
700 | .sigill_fn = fprcvt_sigill, |
701 | }, |
702 | { |
703 | .name = "GCS", |
704 | .at_hwcap = AT_HWCAP, |
705 | .hwcap_bit = HWCAP_GCS, |
706 | .cpuinfo = "gcs", |
707 | .sigill_fn = gcs_sigill, |
708 | .sigill_reliable = true, |
709 | }, |
710 | { |
711 | .name = "JSCVT", |
712 | .at_hwcap = AT_HWCAP, |
713 | .hwcap_bit = HWCAP_JSCVT, |
714 | .cpuinfo = "jscvt", |
715 | .sigill_fn = jscvt_sigill, |
716 | }, |
717 | { |
718 | .name = "LRCPC", |
719 | .at_hwcap = AT_HWCAP, |
720 | .hwcap_bit = HWCAP_LRCPC, |
721 | .cpuinfo = "lrcpc", |
722 | .sigill_fn = lrcpc_sigill, |
723 | }, |
724 | { |
725 | .name = "LRCPC2", |
726 | .at_hwcap = AT_HWCAP, |
727 | .hwcap_bit = HWCAP_ILRCPC, |
728 | .cpuinfo = "ilrcpc", |
729 | .sigill_fn = ilrcpc_sigill, |
730 | }, |
731 | { |
732 | .name = "LRCPC3", |
733 | .at_hwcap = AT_HWCAP2, |
734 | .hwcap_bit = HWCAP2_LRCPC3, |
735 | .cpuinfo = "lrcpc3", |
736 | .sigill_fn = lrcpc3_sigill, |
737 | }, |
738 | { |
739 | .name = "LSE", |
740 | .at_hwcap = AT_HWCAP, |
741 | .hwcap_bit = HWCAP_ATOMICS, |
742 | .cpuinfo = "atomics", |
743 | .sigill_fn = atomics_sigill, |
744 | }, |
745 | { |
746 | .name = "LSE2", |
747 | .at_hwcap = AT_HWCAP, |
748 | .hwcap_bit = HWCAP_USCAT, |
749 | .cpuinfo = "uscat", |
750 | .sigill_fn = atomics_sigill, |
751 | .sigbus_fn = uscat_sigbus, |
752 | .sigbus_reliable = true, |
753 | }, |
754 | { |
755 | .name = "LSE128", |
756 | .at_hwcap = AT_HWCAP2, |
757 | .hwcap_bit = HWCAP2_LSE128, |
758 | .cpuinfo = "lse128", |
759 | .sigill_fn = lse128_sigill, |
760 | }, |
761 | { |
762 | .name = "LUT", |
763 | .at_hwcap = AT_HWCAP2, |
764 | .hwcap_bit = HWCAP2_LUT, |
765 | .cpuinfo = "lut", |
766 | .sigill_fn = lut_sigill, |
767 | }, |
768 | { |
769 | .name = "MOPS", |
770 | .at_hwcap = AT_HWCAP2, |
771 | .hwcap_bit = HWCAP2_MOPS, |
772 | .cpuinfo = "mops", |
773 | .sigill_fn = mops_sigill, |
774 | .sigill_reliable = true, |
775 | }, |
776 | { |
777 | .name = "PMULL", |
778 | .at_hwcap = AT_HWCAP, |
779 | .hwcap_bit = HWCAP_PMULL, |
780 | .cpuinfo = "pmull", |
781 | .sigill_fn = pmull_sigill, |
782 | }, |
783 | { |
784 | .name = "POE", |
785 | .at_hwcap = AT_HWCAP2, |
786 | .hwcap_bit = HWCAP2_POE, |
787 | .cpuinfo = "poe", |
788 | .sigill_fn = poe_sigill, |
789 | .sigill_reliable = true, |
790 | }, |
791 | { |
792 | .name = "RNG", |
793 | .at_hwcap = AT_HWCAP2, |
794 | .hwcap_bit = HWCAP2_RNG, |
795 | .cpuinfo = "rng", |
796 | .sigill_fn = rng_sigill, |
797 | }, |
798 | { |
799 | .name = "RPRFM", |
800 | .at_hwcap = AT_HWCAP2, |
801 | .hwcap_bit = HWCAP2_RPRFM, |
802 | .cpuinfo = "rprfm", |
803 | }, |
804 | { |
805 | .name = "SHA1", |
806 | .at_hwcap = AT_HWCAP, |
807 | .hwcap_bit = HWCAP_SHA1, |
808 | .cpuinfo = "sha1", |
809 | .sigill_fn = sha1_sigill, |
810 | }, |
811 | { |
812 | .name = "SHA2", |
813 | .at_hwcap = AT_HWCAP, |
814 | .hwcap_bit = HWCAP_SHA2, |
815 | .cpuinfo = "sha2", |
816 | .sigill_fn = sha2_sigill, |
817 | }, |
818 | { |
819 | .name = "SHA512", |
820 | .at_hwcap = AT_HWCAP, |
821 | .hwcap_bit = HWCAP_SHA512, |
822 | .cpuinfo = "sha512", |
823 | .sigill_fn = sha512_sigill, |
824 | }, |
825 | { |
826 | .name = "SME", |
827 | .at_hwcap = AT_HWCAP2, |
828 | .hwcap_bit = HWCAP2_SME, |
829 | .cpuinfo = "sme", |
830 | .sigill_fn = sme_sigill, |
831 | .sigill_reliable = true, |
832 | }, |
833 | { |
834 | .name = "SME2", |
835 | .at_hwcap = AT_HWCAP2, |
836 | .hwcap_bit = HWCAP2_SME2, |
837 | .cpuinfo = "sme2", |
838 | .sigill_fn = sme2_sigill, |
839 | .sigill_reliable = true, |
840 | }, |
841 | { |
842 | .name = "SME 2.1", |
843 | .at_hwcap = AT_HWCAP2, |
844 | .hwcap_bit = HWCAP2_SME2P1, |
845 | .cpuinfo = "sme2p1", |
846 | .sigill_fn = sme2p1_sigill, |
847 | }, |
848 | { |
849 | .name = "SME 2.2", |
850 | .at_hwcap = AT_HWCAP, |
851 | .hwcap_bit = HWCAP_SME2P2, |
852 | .cpuinfo = "sme2p2", |
853 | .sigill_fn = sme2p2_sigill, |
854 | }, |
855 | { |
856 | .name = "SME AES", |
857 | .at_hwcap = AT_HWCAP, |
858 | .hwcap_bit = HWCAP_SME_AES, |
859 | .cpuinfo = "smeaes", |
860 | .sigill_fn = sme_aes_sigill, |
861 | }, |
862 | { |
863 | .name = "SME I16I32", |
864 | .at_hwcap = AT_HWCAP2, |
865 | .hwcap_bit = HWCAP2_SME_I16I32, |
866 | .cpuinfo = "smei16i32", |
867 | .sigill_fn = smei16i32_sigill, |
868 | }, |
869 | { |
870 | .name = "SME BI32I32", |
871 | .at_hwcap = AT_HWCAP2, |
872 | .hwcap_bit = HWCAP2_SME_BI32I32, |
873 | .cpuinfo = "smebi32i32", |
874 | .sigill_fn = smebi32i32_sigill, |
875 | }, |
876 | { |
877 | .name = "SME B16B16", |
878 | .at_hwcap = AT_HWCAP2, |
879 | .hwcap_bit = HWCAP2_SME_B16B16, |
880 | .cpuinfo = "smeb16b16", |
881 | .sigill_fn = smeb16b16_sigill, |
882 | }, |
883 | { |
884 | .name = "SME F16F16", |
885 | .at_hwcap = AT_HWCAP2, |
886 | .hwcap_bit = HWCAP2_SME_F16F16, |
887 | .cpuinfo = "smef16f16", |
888 | .sigill_fn = smef16f16_sigill, |
889 | }, |
890 | { |
891 | .name = "SME F8F16", |
892 | .at_hwcap = AT_HWCAP2, |
893 | .hwcap_bit = HWCAP2_SME_F8F16, |
894 | .cpuinfo = "smef8f16", |
895 | .sigill_fn = smef8f16_sigill, |
896 | }, |
897 | { |
898 | .name = "SME F8F32", |
899 | .at_hwcap = AT_HWCAP2, |
900 | .hwcap_bit = HWCAP2_SME_F8F32, |
901 | .cpuinfo = "smef8f32", |
902 | .sigill_fn = smef8f32_sigill, |
903 | }, |
904 | { |
905 | .name = "SME LUTV2", |
906 | .at_hwcap = AT_HWCAP2, |
907 | .hwcap_bit = HWCAP2_SME_LUTV2, |
908 | .cpuinfo = "smelutv2", |
909 | .sigill_fn = smelutv2_sigill, |
910 | }, |
911 | { |
912 | .name = "SME SBITPERM", |
913 | .at_hwcap = AT_HWCAP, |
914 | .hwcap_bit = HWCAP_SME_SBITPERM, |
915 | .cpuinfo = "smesbitperm", |
916 | .sigill_fn = sme_sbitperm_sigill, |
917 | }, |
918 | { |
919 | .name = "SME SF8FMA", |
920 | .at_hwcap = AT_HWCAP2, |
921 | .hwcap_bit = HWCAP2_SME_SF8FMA, |
922 | .cpuinfo = "smesf8fma", |
923 | .sigill_fn = smesf8fma_sigill, |
924 | }, |
925 | { |
926 | .name = "SME SF8DP2", |
927 | .at_hwcap = AT_HWCAP2, |
928 | .hwcap_bit = HWCAP2_SME_SF8DP2, |
929 | .cpuinfo = "smesf8dp2", |
930 | .sigill_fn = smesf8dp2_sigill, |
931 | }, |
932 | { |
933 | .name = "SME SF8DP4", |
934 | .at_hwcap = AT_HWCAP2, |
935 | .hwcap_bit = HWCAP2_SME_SF8DP4, |
936 | .cpuinfo = "smesf8dp4", |
937 | .sigill_fn = smesf8dp4_sigill, |
938 | }, |
939 | { |
940 | .name = "SME SFEXPA", |
941 | .at_hwcap = AT_HWCAP, |
942 | .hwcap_bit = HWCAP_SME_SFEXPA, |
943 | .cpuinfo = "smesfexpa", |
944 | .sigill_fn = smesfexpa_sigill, |
945 | }, |
946 | { |
947 | .name = "SME SMOP4", |
948 | .at_hwcap = AT_HWCAP, |
949 | .hwcap_bit = HWCAP_SME_SMOP4, |
950 | .cpuinfo = "smesmop4", |
951 | .sigill_fn = smesmop4_sigill, |
952 | }, |
953 | { |
954 | .name = "SME STMOP", |
955 | .at_hwcap = AT_HWCAP, |
956 | .hwcap_bit = HWCAP_SME_STMOP, |
957 | .cpuinfo = "smestmop", |
958 | .sigill_fn = smestmop_sigill, |
959 | }, |
960 | { |
961 | .name = "SVE", |
962 | .at_hwcap = AT_HWCAP, |
963 | .hwcap_bit = HWCAP_SVE, |
964 | .cpuinfo = "sve", |
965 | .sigill_fn = sve_sigill, |
966 | .sigill_reliable = true, |
967 | }, |
968 | { |
969 | .name = "SVE 2", |
970 | .at_hwcap = AT_HWCAP2, |
971 | .hwcap_bit = HWCAP2_SVE2, |
972 | .cpuinfo = "sve2", |
973 | .sigill_fn = sve2_sigill, |
974 | }, |
975 | { |
976 | .name = "SVE 2.1", |
977 | .at_hwcap = AT_HWCAP2, |
978 | .hwcap_bit = HWCAP2_SVE2P1, |
979 | .cpuinfo = "sve2p1", |
980 | .sigill_fn = sve2p1_sigill, |
981 | }, |
982 | { |
983 | .name = "SVE 2.2", |
984 | .at_hwcap = AT_HWCAP, |
985 | .hwcap_bit = HWCAP_SVE2P2, |
986 | .cpuinfo = "sve2p2", |
987 | .sigill_fn = sve2p2_sigill, |
988 | }, |
989 | { |
990 | .name = "SVE AES", |
991 | .at_hwcap = AT_HWCAP2, |
992 | .hwcap_bit = HWCAP2_SVEAES, |
993 | .cpuinfo = "sveaes", |
994 | .sigill_fn = sveaes_sigill, |
995 | }, |
996 | { |
997 | .name = "SVE AES2", |
998 | .at_hwcap = AT_HWCAP, |
999 | .hwcap_bit = HWCAP_SVE_AES2, |
1000 | .cpuinfo = "sveaes2", |
1001 | .sigill_fn = sveaes2_sigill, |
1002 | }, |
1003 | { |
1004 | .name = "SVE BFSCALE", |
1005 | .at_hwcap = AT_HWCAP, |
1006 | .hwcap_bit = HWCAP_SVE_BFSCALE, |
1007 | .cpuinfo = "svebfscale", |
1008 | .sigill_fn = svebfscale_sigill, |
1009 | }, |
1010 | { |
1011 | .name = "SVE ELTPERM", |
1012 | .at_hwcap = AT_HWCAP, |
1013 | .hwcap_bit = HWCAP_SVE_ELTPERM, |
1014 | .cpuinfo = "sveeltperm", |
1015 | .sigill_fn = sveeltperm_sigill, |
1016 | }, |
1017 | { |
1018 | .name = "SVE F16MM", |
1019 | .at_hwcap = AT_HWCAP, |
1020 | .hwcap_bit = HWCAP_SVE_F16MM, |
1021 | .cpuinfo = "svef16mm", |
1022 | .sigill_fn = svef16mm_sigill, |
1023 | }, |
1024 | { |
1025 | .name = "SVE2 B16B16", |
1026 | .at_hwcap = AT_HWCAP2, |
1027 | .hwcap_bit = HWCAP2_SVE_B16B16, |
1028 | .cpuinfo = "sveb16b16", |
1029 | .sigill_fn = sveb16b16_sigill, |
1030 | }, |
1031 | { |
1032 | .name = "SVE2 PMULL", |
1033 | .at_hwcap = AT_HWCAP2, |
1034 | .hwcap_bit = HWCAP2_SVEPMULL, |
1035 | .cpuinfo = "svepmull", |
1036 | .sigill_fn = svepmull_sigill, |
1037 | }, |
1038 | { |
1039 | .name = "SVE2 BITPERM", |
1040 | .at_hwcap = AT_HWCAP2, |
1041 | .hwcap_bit = HWCAP2_SVEBITPERM, |
1042 | .cpuinfo = "svebitperm", |
1043 | .sigill_fn = svebitperm_sigill, |
1044 | }, |
1045 | { |
1046 | .name = "SVE2 SHA3", |
1047 | .at_hwcap = AT_HWCAP2, |
1048 | .hwcap_bit = HWCAP2_SVESHA3, |
1049 | .cpuinfo = "svesha3", |
1050 | .sigill_fn = svesha3_sigill, |
1051 | }, |
1052 | { |
1053 | .name = "SVE2 SM4", |
1054 | .at_hwcap = AT_HWCAP2, |
1055 | .hwcap_bit = HWCAP2_SVESM4, |
1056 | .cpuinfo = "svesm4", |
1057 | .sigill_fn = svesm4_sigill, |
1058 | }, |
1059 | { |
1060 | .name = "SVE2 I8MM", |
1061 | .at_hwcap = AT_HWCAP2, |
1062 | .hwcap_bit = HWCAP2_SVEI8MM, |
1063 | .cpuinfo = "svei8mm", |
1064 | .sigill_fn = svei8mm_sigill, |
1065 | }, |
1066 | { |
1067 | .name = "SVE2 F32MM", |
1068 | .at_hwcap = AT_HWCAP2, |
1069 | .hwcap_bit = HWCAP2_SVEF32MM, |
1070 | .cpuinfo = "svef32mm", |
1071 | .sigill_fn = svef32mm_sigill, |
1072 | }, |
1073 | { |
1074 | .name = "SVE2 F64MM", |
1075 | .at_hwcap = AT_HWCAP2, |
1076 | .hwcap_bit = HWCAP2_SVEF64MM, |
1077 | .cpuinfo = "svef64mm", |
1078 | .sigill_fn = svef64mm_sigill, |
1079 | }, |
1080 | { |
1081 | .name = "SVE2 BF16", |
1082 | .at_hwcap = AT_HWCAP2, |
1083 | .hwcap_bit = HWCAP2_SVEBF16, |
1084 | .cpuinfo = "svebf16", |
1085 | .sigill_fn = svebf16_sigill, |
1086 | }, |
1087 | { |
1088 | .name = "SVE2 EBF16", |
1089 | .at_hwcap = AT_HWCAP2, |
1090 | .hwcap_bit = HWCAP2_SVE_EBF16, |
1091 | .cpuinfo = "sveebf16", |
1092 | }, |
1093 | { |
1094 | .name = "HBC", |
1095 | .at_hwcap = AT_HWCAP2, |
1096 | .hwcap_bit = HWCAP2_HBC, |
1097 | .cpuinfo = "hbc", |
1098 | .sigill_fn = hbc_sigill, |
1099 | .sigill_reliable = true, |
1100 | }, |
1101 | }; |
1102 | |
1103 | typedef void (*sighandler_fn)(int, siginfo_t *, void *); |
1104 | |
1105 | #define DEF_SIGHANDLER_FUNC(SIG, NUM) \ |
1106 | static bool seen_##SIG; \ |
1107 | static void handle_##SIG(int sig, siginfo_t *info, void *context) \ |
1108 | { \ |
1109 | ucontext_t *uc = context; \ |
1110 | \ |
1111 | seen_##SIG = true; \ |
1112 | /* Skip over the offending instruction */ \ |
1113 | uc->uc_mcontext.pc += 4; \ |
1114 | } |
1115 | |
1116 | DEF_SIGHANDLER_FUNC(sigill, SIGILL); |
1117 | DEF_SIGHANDLER_FUNC(sigbus, SIGBUS); |
1118 | |
1119 | bool cpuinfo_present(const char *name) |
1120 | { |
1121 | FILE *f; |
1122 | char buf[2048], name_space[30], name_newline[30]; |
1123 | char *s; |
1124 | |
1125 | /* |
1126 | * The feature should appear with a leading space and either a |
1127 | * trailing space or a newline. |
1128 | */ |
1129 | snprintf(name_space, sizeof(name_space), " %s ", name); |
1130 | snprintf(name_newline, sizeof(name_newline), " %s\n", name); |
1131 | |
1132 | f = fopen("/proc/cpuinfo", "r"); |
1133 | if (!f) { |
1134 | ksft_print_msg(msg: "Failed to open /proc/cpuinfo\n"); |
1135 | return false; |
1136 | } |
1137 | |
1138 | while (fgets(buf, sizeof(buf), f)) { |
1139 | /* Features: line? */ |
1140 | if (strncmp(buf, "Features\t:", strlen( "Features\t:")) != 0) |
1141 | continue; |
1142 | |
1143 | /* All CPUs should be symmetric, don't read any more */ |
1144 | fclose(f); |
1145 | |
1146 | s = strstr(buf, name_space); |
1147 | if (s) |
1148 | return true; |
1149 | s = strstr(buf, name_newline); |
1150 | if (s) |
1151 | return true; |
1152 | |
1153 | return false; |
1154 | } |
1155 | |
1156 | ksft_print_msg(msg: "Failed to find Features in /proc/cpuinfo\n"); |
1157 | fclose(f); |
1158 | return false; |
1159 | } |
1160 | |
1161 | static int install_sigaction(int signum, sighandler_fn handler) |
1162 | { |
1163 | int ret; |
1164 | struct sigaction sa; |
1165 | |
1166 | memset(&sa, 0, sizeof(sa)); |
1167 | sa.sa_sigaction = handler; |
1168 | sa.sa_flags = SA_RESTART | SA_SIGINFO; |
1169 | sigemptyset(&sa.sa_mask); |
1170 | ret = sigaction(signum, &sa, NULL); |
1171 | if (ret < 0) |
1172 | ksft_exit_fail_msg("Failed to install SIGNAL handler: %s (%d)\n", |
1173 | strerror(errno), errno); |
1174 | |
1175 | return ret; |
1176 | } |
1177 | |
1178 | static void uninstall_sigaction(int signum) |
1179 | { |
1180 | if (sigaction(signum, NULL, NULL) < 0) |
1181 | ksft_exit_fail_msg("Failed to uninstall SIGNAL handler: %s (%d)\n", |
1182 | strerror(errno), errno); |
1183 | } |
1184 | |
1185 | #define DEF_INST_RAISE_SIG(SIG, NUM) \ |
1186 | static bool inst_raise_##SIG(const struct hwcap_data *hwcap, \ |
1187 | bool have_hwcap) \ |
1188 | { \ |
1189 | if (!hwcap->SIG##_fn) { \ |
1190 | ksft_test_result_skip(#SIG"_%s\n", hwcap->name); \ |
1191 | /* assume that it would raise exception in default */ \ |
1192 | return true; \ |
1193 | } \ |
1194 | \ |
1195 | install_sigaction(NUM, handle_##SIG); \ |
1196 | \ |
1197 | seen_##SIG = false; \ |
1198 | hwcap->SIG##_fn(); \ |
1199 | \ |
1200 | if (have_hwcap) { \ |
1201 | /* Should be able to use the extension */ \ |
1202 | ksft_test_result(!seen_##SIG, \ |
1203 | #SIG"_%s\n", hwcap->name); \ |
1204 | } else if (hwcap->SIG##_reliable) { \ |
1205 | /* Guaranteed a SIGNAL */ \ |
1206 | ksft_test_result(seen_##SIG, \ |
1207 | #SIG"_%s\n", hwcap->name); \ |
1208 | } else { \ |
1209 | /* Missing SIGNAL might be fine */ \ |
1210 | ksft_print_msg(#SIG"_%sreported for %s\n", \ |
1211 | seen_##SIG ? "" : "not ", \ |
1212 | hwcap->name); \ |
1213 | ksft_test_result_skip(#SIG"_%s\n", \ |
1214 | hwcap->name); \ |
1215 | } \ |
1216 | \ |
1217 | uninstall_sigaction(NUM); \ |
1218 | return seen_##SIG; \ |
1219 | } |
1220 | |
1221 | DEF_INST_RAISE_SIG(sigill, SIGILL); |
1222 | DEF_INST_RAISE_SIG(sigbus, SIGBUS); |
1223 | |
1224 | int main(void) |
1225 | { |
1226 | int i; |
1227 | const struct hwcap_data *hwcap; |
1228 | bool have_cpuinfo, have_hwcap, raise_sigill; |
1229 | |
1230 | ksft_print_header(); |
1231 | ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP); |
1232 | |
1233 | for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { |
1234 | hwcap = &hwcaps[i]; |
1235 | |
1236 | have_hwcap = getauxval(hwcap->at_hwcap) & hwcap->hwcap_bit; |
1237 | have_cpuinfo = cpuinfo_present(hwcap->cpuinfo); |
1238 | |
1239 | if (have_hwcap) |
1240 | ksft_print_msg("%s present\n", hwcap->name); |
1241 | |
1242 | ksft_test_result(have_hwcap == have_cpuinfo, |
1243 | "cpuinfo_match_%s\n", hwcap->name); |
1244 | |
1245 | /* |
1246 | * Testing for SIGBUS only makes sense after make sure |
1247 | * that the instruction does not cause a SIGILL signal. |
1248 | */ |
1249 | raise_sigill = inst_raise_sigill(hwcap, have_hwcap); |
1250 | if (!raise_sigill) |
1251 | inst_raise_sigbus(hwcap, have_hwcap); |
1252 | else |
1253 | ksft_test_result_skip("sigbus_%s\n", hwcap->name); |
1254 | } |
1255 | |
1256 | ksft_print_cnts(); |
1257 | |
1258 | return 0; |
1259 | } |
1260 |
Definitions
- aes_sigill
- atomics_sigill
- cmpbr_sigill
- crc32_sigill
- cssc_sigill
- f8cvt_sigill
- f8dp2_sigill
- f8dp4_sigill
- f8fma_sigill
- f8mm4_sigill
- f8mm8_sigill
- faminmax_sigill
- fp_sigill
- fpmr_sigill
- fprcvt_sigill
- gcs_sigill
- ilrcpc_sigill
- jscvt_sigill
- lrcpc_sigill
- lse128_sigill
- lut_sigill
- mops_sigill
- pmull_sigill
- poe_sigill
- rng_sigill
- sha1_sigill
- sha2_sigill
- sha512_sigill
- sme_sigill
- sme2_sigill
- sme2p1_sigill
- sme2p2_sigill
- sme_aes_sigill
- sme_sbitperm_sigill
- smei16i32_sigill
- smebi32i32_sigill
- smeb16b16_sigill
- smef16f16_sigill
- smef8f16_sigill
- smef8f32_sigill
- smelutv2_sigill
- smesf8dp2_sigill
- smesf8dp4_sigill
- smesf8fma_sigill
- smesfexpa_sigill
- smesmop4_sigill
- smestmop_sigill
- sve_sigill
- sve2_sigill
- sve2p1_sigill
- sve2p2_sigill
- sveaes_sigill
- sveaes2_sigill
- sveb16b16_sigill
- svebfscale_sigill
- svef16mm_sigill
- svepmull_sigill
- svebitperm_sigill
- svesha3_sigill
- sveeltperm_sigill
- svesm4_sigill
- svei8mm_sigill
- svef32mm_sigill
- svef64mm_sigill
- svebf16_sigill
- hbc_sigill
- uscat_sigbus
- lrcpc3_sigill
- hwcap_data
- hwcaps
- cpuinfo_present
- install_sigaction
- uninstall_sigaction
Improve your Profiling and Debugging skills
Find out more