@@ -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+
453456bool 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