Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

kselftest/arm64: add DEF_SIGHANDLER_FUNC() and DEF_INST_RAISE_SIG() helpers

Add macro definition functions DEF_SIGHANDLER_FUNC() and
DEF_INST_RAISE_SIG() helpers.

Furthermore, there is no need to modify the default SIGILL handling
function throughout the entire testing lifecycle in the main() function.
It is reasonable to narrow the scope to the context of the sig_fn
function only.

This is a pre-patch for the subsequent SIGBUS handler patch.

Signed-off-by: Zeng Heng <zengheng4@huawei.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20230808134036.668954-4-zengheng4@huawei.com
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Zeng Heng and committed by
Will Deacon
71b634ab 09d2e95a

+74 -42
+74 -42
tools/testing/selftests/arm64/abi/hwcap.c
··· 438 438 }, 439 439 }; 440 440 441 - static bool seen_sigill; 441 + typedef void (*sighandler_fn)(int, siginfo_t *, void *); 442 442 443 - static void handle_sigill(int sig, siginfo_t *info, void *context) 444 - { 445 - ucontext_t *uc = context; 446 - 447 - seen_sigill = true; 448 - 449 - /* Skip over the offending instruction */ 450 - uc->uc_mcontext.pc += 4; 443 + #define DEF_SIGHANDLER_FUNC(SIG, NUM) \ 444 + static bool seen_##SIG; \ 445 + static void handle_##SIG(int sig, siginfo_t *info, void *context) \ 446 + { \ 447 + ucontext_t *uc = context; \ 448 + \ 449 + seen_##SIG = true; \ 450 + /* Skip over the offending instruction */ \ 451 + uc->uc_mcontext.pc += 4; \ 451 452 } 453 + 454 + DEF_SIGHANDLER_FUNC(sigill, SIGILL); 452 455 453 456 bool cpuinfo_present(const char *name) 454 457 { ··· 495 492 return false; 496 493 } 497 494 498 - int main(void) 495 + static int install_sigaction(int signum, sighandler_fn handler) 499 496 { 500 - const struct hwcap_data *hwcap; 501 - int i, ret; 502 - bool have_cpuinfo, have_hwcap; 497 + int ret; 503 498 struct sigaction sa; 504 499 505 - ksft_print_header(); 506 - ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP); 507 - 508 500 memset(&sa, 0, sizeof(sa)); 509 - sa.sa_sigaction = handle_sigill; 501 + sa.sa_sigaction = handler; 510 502 sa.sa_flags = SA_RESTART | SA_SIGINFO; 511 503 sigemptyset(&sa.sa_mask); 512 - ret = sigaction(SIGILL, &sa, NULL); 504 + ret = sigaction(signum, &sa, NULL); 513 505 if (ret < 0) 514 506 ksft_exit_fail_msg("Failed to install SIGILL handler: %s (%d)\n", 515 507 strerror(errno), errno); 508 + 509 + return ret; 510 + } 511 + 512 + static void uninstall_sigaction(int signum) 513 + { 514 + if (sigaction(signum, NULL, NULL) < 0) 515 + ksft_exit_fail_msg("Failed to uninstall SIGILL handler: %s (%d)\n", 516 + strerror(errno), errno); 517 + } 518 + 519 + #define DEF_INST_RAISE_SIG(SIG, NUM) \ 520 + static bool inst_raise_##SIG(const struct hwcap_data *hwcap, \ 521 + bool have_hwcap) \ 522 + { \ 523 + if (!hwcap->SIG##_fn) { \ 524 + ksft_test_result_skip(#SIG"_%s\n", hwcap->name); \ 525 + /* assume that it would raise exception in default */ \ 526 + return true; \ 527 + } \ 528 + \ 529 + install_sigaction(NUM, handle_##SIG); \ 530 + \ 531 + seen_##SIG = false; \ 532 + hwcap->SIG##_fn(); \ 533 + \ 534 + if (have_hwcap) { \ 535 + /* Should be able to use the extension */ \ 536 + ksft_test_result(!seen_##SIG, \ 537 + #SIG"_%s\n", hwcap->name); \ 538 + } else if (hwcap->SIG##_reliable) { \ 539 + /* Guaranteed a SIGNAL */ \ 540 + ksft_test_result(seen_##SIG, \ 541 + #SIG"_%s\n", hwcap->name); \ 542 + } else { \ 543 + /* Missing SIGNAL might be fine */ \ 544 + ksft_print_msg(#SIG"_%sreported for %s\n", \ 545 + seen_##SIG ? "" : "not ", \ 546 + hwcap->name); \ 547 + ksft_test_result_skip(#SIG"_%s\n", \ 548 + hwcap->name); \ 549 + } \ 550 + \ 551 + uninstall_sigaction(NUM); \ 552 + return seen_##SIG; \ 553 + } 554 + 555 + DEF_INST_RAISE_SIG(sigill, SIGILL); 556 + 557 + int main(void) 558 + { 559 + int i; 560 + const struct hwcap_data *hwcap; 561 + bool have_cpuinfo, have_hwcap; 562 + 563 + ksft_print_header(); 564 + ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP); 516 565 517 566 for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { 518 567 hwcap = &hwcaps[i]; ··· 578 523 ksft_test_result(have_hwcap == have_cpuinfo, 579 524 "cpuinfo_match_%s\n", hwcap->name); 580 525 581 - if (hwcap->sigill_fn) { 582 - seen_sigill = false; 583 - hwcap->sigill_fn(); 584 - 585 - if (have_hwcap) { 586 - /* Should be able to use the extension */ 587 - ksft_test_result(!seen_sigill, "sigill_%s\n", 588 - hwcap->name); 589 - } else if (hwcap->sigill_reliable) { 590 - /* Guaranteed a SIGILL */ 591 - ksft_test_result(seen_sigill, "sigill_%s\n", 592 - hwcap->name); 593 - } else { 594 - /* Missing SIGILL might be fine */ 595 - ksft_print_msg("SIGILL %sreported for %s\n", 596 - seen_sigill ? "" : "not ", 597 - hwcap->name); 598 - ksft_test_result_skip("sigill_%s\n", 599 - hwcap->name); 600 - } 601 - } else { 602 - ksft_test_result_skip("sigill_%s\n", 603 - hwcap->name); 604 - } 526 + inst_raise_sigill(hwcap, have_hwcap); 605 527 } 606 528 607 529 ksft_print_cnts();