Skip to content

Commit fd49cf0

Browse files
henryZewilldeacon
authored andcommitted
kselftest/arm64: add test item that support to capturing the SIGBUS signal
Some enhanced features, such as the LSE2 feature, do not result in SILLILL if LSE2 is missing and LSE is present, but will generate a SIGBUS exception when atomic access unaligned. Therefore, we add test item to test this type of features. Notice that testing for SIGBUS only makes sense after make sure that the instruction does not cause a SIGILL signal. 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 71b634a commit fd49cf0

File tree

1 file changed

+23
-10
lines changed
  • tools/testing/selftests/arm64/abi

1 file changed

+23
-10
lines changed

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

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,20 @@
1919

2020
#include "../../kselftest.h"
2121

22-
#define TESTS_PER_HWCAP 2
22+
#define TESTS_PER_HWCAP 3
2323

2424
/*
25-
* Function expected to generate SIGILL when the feature is not
26-
* supported and return when it is supported. If SIGILL is generated
27-
* then the handler must be able to skip over the instruction safely.
25+
* Function expected to generate exception when the feature is not
26+
* supported and return when it is supported. If the specific exception
27+
* is generated then the handler must be able to skip over the
28+
* instruction safely.
2829
*
2930
* Note that it is expected that for many architecture extensions
3031
* there are no specific traps due to no architecture state being
3132
* added so we may not fault if running on a kernel which doesn't know
3233
* to add the hwcap.
3334
*/
34-
typedef void (*sigill_fn)(void);
35+
typedef void (*sig_fn)(void);
3536

3637
static void crc32_sigill(void)
3738
{
@@ -235,8 +236,10 @@ static const struct hwcap_data {
235236
unsigned long at_hwcap;
236237
unsigned long hwcap_bit;
237238
const char *cpuinfo;
238-
sigill_fn sigill_fn;
239+
sig_fn sigill_fn;
239240
bool sigill_reliable;
241+
sig_fn sigbus_fn;
242+
bool sigbus_reliable;
240243
} hwcaps[] = {
241244
{
242245
.name = "CRC32",
@@ -452,6 +455,7 @@ static void handle_##SIG(int sig, siginfo_t *info, void *context) \
452455
}
453456

454457
DEF_SIGHANDLER_FUNC(sigill, SIGILL);
458+
DEF_SIGHANDLER_FUNC(sigbus, SIGBUS);
455459

456460
bool cpuinfo_present(const char *name)
457461
{
@@ -506,7 +510,7 @@ static int install_sigaction(int signum, sighandler_fn handler)
506510
sigemptyset(&sa.sa_mask);
507511
ret = sigaction(signum, &sa, NULL);
508512
if (ret < 0)
509-
ksft_exit_fail_msg("Failed to install SIGILL handler: %s (%d)\n",
513+
ksft_exit_fail_msg("Failed to install SIGNAL handler: %s (%d)\n",
510514
strerror(errno), errno);
511515

512516
return ret;
@@ -515,7 +519,7 @@ static int install_sigaction(int signum, sighandler_fn handler)
515519
static void uninstall_sigaction(int signum)
516520
{
517521
if (sigaction(signum, NULL, NULL) < 0)
518-
ksft_exit_fail_msg("Failed to uninstall SIGILL handler: %s (%d)\n",
522+
ksft_exit_fail_msg("Failed to uninstall SIGNAL handler: %s (%d)\n",
519523
strerror(errno), errno);
520524
}
521525

@@ -556,12 +560,13 @@ static bool inst_raise_##SIG(const struct hwcap_data *hwcap, \
556560
}
557561

558562
DEF_INST_RAISE_SIG(sigill, SIGILL);
563+
DEF_INST_RAISE_SIG(sigbus, SIGBUS);
559564

560565
int main(void)
561566
{
562567
int i;
563568
const struct hwcap_data *hwcap;
564-
bool have_cpuinfo, have_hwcap;
569+
bool have_cpuinfo, have_hwcap, raise_sigill;
565570

566571
ksft_print_header();
567572
ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP);
@@ -578,7 +583,15 @@ int main(void)
578583
ksft_test_result(have_hwcap == have_cpuinfo,
579584
"cpuinfo_match_%s\n", hwcap->name);
580585

581-
inst_raise_sigill(hwcap, have_hwcap);
586+
/*
587+
* Testing for SIGBUS only makes sense after make sure
588+
* that the instruction does not cause a SIGILL signal.
589+
*/
590+
raise_sigill = inst_raise_sigill(hwcap, have_hwcap);
591+
if (!raise_sigill)
592+
inst_raise_sigbus(hwcap, have_hwcap);
593+
else
594+
ksft_test_result_skip("sigbus_%s\n", hwcap->name);
582595
}
583596

584597
ksft_print_cnts();

0 commit comments

Comments
 (0)