Skip to content

Commit 71b634a

Browse files
henryZewilldeacon
authored andcommitted
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 <[email protected]> Reviewed-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 09d2e95 commit 71b634a

File tree

1 file changed

+75
-43
lines changed
  • tools/testing/selftests/arm64/abi

1 file changed

+75
-43
lines changed

tools/testing/selftests/arm64/abi/hwcap.c

Lines changed: 75 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -438,18 +438,21 @@ static const struct hwcap_data {
438438
},
439439
};
440440

441-
static bool seen_sigill;
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;
441+
typedef void (*sighandler_fn)(int, siginfo_t *, void *);
442+
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; \
451452
}
452453

454+
DEF_SIGHANDLER_FUNC(sigill, SIGILL);
455+
453456
bool cpuinfo_present(const char *name)
454457
{
455458
FILE *f;
@@ -492,25 +495,77 @@ bool cpuinfo_present(const char *name)
492495
return false;
493496
}
494497

495-
int main(void)
498+
static int install_sigaction(int signum, sighandler_fn handler)
496499
{
497-
const struct hwcap_data *hwcap;
498-
int i, ret;
499-
bool have_cpuinfo, have_hwcap;
500+
int ret;
500501
struct sigaction sa;
501502

502-
ksft_print_header();
503-
ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP);
504-
505503
memset(&sa, 0, sizeof(sa));
506-
sa.sa_sigaction = handle_sigill;
504+
sa.sa_sigaction = handler;
507505
sa.sa_flags = SA_RESTART | SA_SIGINFO;
508506
sigemptyset(&sa.sa_mask);
509-
ret = sigaction(SIGILL, &sa, NULL);
507+
ret = sigaction(signum, &sa, NULL);
510508
if (ret < 0)
511509
ksft_exit_fail_msg("Failed to install SIGILL handler: %s (%d)\n",
512510
strerror(errno), errno);
513511

512+
return ret;
513+
}
514+
515+
static void uninstall_sigaction(int signum)
516+
{
517+
if (sigaction(signum, NULL, NULL) < 0)
518+
ksft_exit_fail_msg("Failed to uninstall SIGILL handler: %s (%d)\n",
519+
strerror(errno), errno);
520+
}
521+
522+
#define DEF_INST_RAISE_SIG(SIG, NUM) \
523+
static bool inst_raise_##SIG(const struct hwcap_data *hwcap, \
524+
bool have_hwcap) \
525+
{ \
526+
if (!hwcap->SIG##_fn) { \
527+
ksft_test_result_skip(#SIG"_%s\n", hwcap->name); \
528+
/* assume that it would raise exception in default */ \
529+
return true; \
530+
} \
531+
\
532+
install_sigaction(NUM, handle_##SIG); \
533+
\
534+
seen_##SIG = false; \
535+
hwcap->SIG##_fn(); \
536+
\
537+
if (have_hwcap) { \
538+
/* Should be able to use the extension */ \
539+
ksft_test_result(!seen_##SIG, \
540+
#SIG"_%s\n", hwcap->name); \
541+
} else if (hwcap->SIG##_reliable) { \
542+
/* Guaranteed a SIGNAL */ \
543+
ksft_test_result(seen_##SIG, \
544+
#SIG"_%s\n", hwcap->name); \
545+
} else { \
546+
/* Missing SIGNAL might be fine */ \
547+
ksft_print_msg(#SIG"_%sreported for %s\n", \
548+
seen_##SIG ? "" : "not ", \
549+
hwcap->name); \
550+
ksft_test_result_skip(#SIG"_%s\n", \
551+
hwcap->name); \
552+
} \
553+
\
554+
uninstall_sigaction(NUM); \
555+
return seen_##SIG; \
556+
}
557+
558+
DEF_INST_RAISE_SIG(sigill, SIGILL);
559+
560+
int main(void)
561+
{
562+
int i;
563+
const struct hwcap_data *hwcap;
564+
bool have_cpuinfo, have_hwcap;
565+
566+
ksft_print_header();
567+
ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP);
568+
514569
for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
515570
hwcap = &hwcaps[i];
516571

@@ -523,30 +578,7 @@ int main(void)
523578
ksft_test_result(have_hwcap == have_cpuinfo,
524579
"cpuinfo_match_%s\n", hwcap->name);
525580

526-
if (hwcap->sigill_fn) {
527-
seen_sigill = false;
528-
hwcap->sigill_fn();
529-
530-
if (have_hwcap) {
531-
/* Should be able to use the extension */
532-
ksft_test_result(!seen_sigill, "sigill_%s\n",
533-
hwcap->name);
534-
} else if (hwcap->sigill_reliable) {
535-
/* Guaranteed a SIGILL */
536-
ksft_test_result(seen_sigill, "sigill_%s\n",
537-
hwcap->name);
538-
} else {
539-
/* Missing SIGILL might be fine */
540-
ksft_print_msg("SIGILL %sreported for %s\n",
541-
seen_sigill ? "" : "not ",
542-
hwcap->name);
543-
ksft_test_result_skip("sigill_%s\n",
544-
hwcap->name);
545-
}
546-
} else {
547-
ksft_test_result_skip("sigill_%s\n",
548-
hwcap->name);
549-
}
581+
inst_raise_sigill(hwcap, have_hwcap);
550582
}
551583

552584
ksft_print_cnts();

0 commit comments

Comments
 (0)