#include "../../kselftest.h"
 
-#define TESTS_PER_HWCAP 2
+#define TESTS_PER_HWCAP 3
 
 /*
- * Function expected to generate SIGILL when the feature is not
- * supported and return when it is supported. If SIGILL is generated
- * then the handler must be able to skip over the instruction safely.
+ * Function expected to generate exception when the feature is not
+ * supported and return when it is supported. If the specific exception
+ * is generated then the handler must be able to skip over the
+ * instruction safely.
  *
  * Note that it is expected that for many architecture extensions
  * there are no specific traps due to no architecture state being
  * added so we may not fault if running on a kernel which doesn't know
  * to add the hwcap.
  */
-typedef void (*sigill_fn)(void);
+typedef void (*sig_fn)(void);
 
 static void crc32_sigill(void)
 {
        unsigned long at_hwcap;
        unsigned long hwcap_bit;
        const char *cpuinfo;
-       sigill_fn sigill_fn;
+       sig_fn sigill_fn;
        bool sigill_reliable;
+       sig_fn sigbus_fn;
+       bool sigbus_reliable;
 } hwcaps[] = {
        {
                .name = "CRC32",
 }
 
 DEF_SIGHANDLER_FUNC(sigill, SIGILL);
+DEF_SIGHANDLER_FUNC(sigbus, SIGBUS);
 
 bool cpuinfo_present(const char *name)
 {
        sigemptyset(&sa.sa_mask);
        ret = sigaction(signum, &sa, NULL);
        if (ret < 0)
-               ksft_exit_fail_msg("Failed to install SIGILL handler: %s (%d)\n",
+               ksft_exit_fail_msg("Failed to install SIGNAL handler: %s (%d)\n",
                                   strerror(errno), errno);
 
        return ret;
 static void uninstall_sigaction(int signum)
 {
        if (sigaction(signum, NULL, NULL) < 0)
-               ksft_exit_fail_msg("Failed to uninstall SIGILL handler: %s (%d)\n",
+               ksft_exit_fail_msg("Failed to uninstall SIGNAL handler: %s (%d)\n",
                                   strerror(errno), errno);
 }
 
 }
 
 DEF_INST_RAISE_SIG(sigill, SIGILL);
+DEF_INST_RAISE_SIG(sigbus, SIGBUS);
 
 int main(void)
 {
        int i;
        const struct hwcap_data *hwcap;
-       bool have_cpuinfo, have_hwcap;
+       bool have_cpuinfo, have_hwcap, raise_sigill;
 
        ksft_print_header();
        ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP);
                ksft_test_result(have_hwcap == have_cpuinfo,
                                 "cpuinfo_match_%s\n", hwcap->name);
 
-               inst_raise_sigill(hwcap, have_hwcap);
+               /*
+                * Testing for SIGBUS only makes sense after make sure
+                * that the instruction does not cause a SIGILL signal.
+                */
+               raise_sigill = inst_raise_sigill(hwcap, have_hwcap);
+               if (!raise_sigill)
+                       inst_raise_sigbus(hwcap, have_hwcap);
+               else
+                       ksft_test_result_skip("sigbus_%s\n", hwcap->name);
        }
 
        ksft_print_cnts();