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