1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright 2016, Chris Smart, IBM Corporation. |
4 | * |
5 | * Calls to copy_first which are not 128-byte aligned should be |
6 | * caught and sent a SIGBUS. |
7 | */ |
8 | |
9 | #include <signal.h> |
10 | #include <string.h> |
11 | #include <unistd.h> |
12 | #include "utils.h" |
13 | #include "instructions.h" |
14 | |
15 | unsigned int expected_instruction = PPC_INST_COPY_FIRST; |
16 | unsigned int instruction_mask = 0xfc2007fe; |
17 | |
18 | void signal_action_handler(int signal_num, siginfo_t *info, void *ptr) |
19 | { |
20 | ucontext_t *ctx = ptr; |
21 | #ifdef __powerpc64__ |
22 | unsigned int *pc = (unsigned int *)ctx->uc_mcontext.gp_regs[PT_NIP]; |
23 | #else |
24 | unsigned int *pc = (unsigned int *)ctx->uc_mcontext.uc_regs->gregs[PT_NIP]; |
25 | #endif |
26 | |
27 | /* |
28 | * Check that the signal was on the correct instruction, using a |
29 | * mask because the compiler assigns the register at RB. |
30 | */ |
31 | if ((*pc & instruction_mask) == expected_instruction) |
32 | _exit(0); /* We hit the right instruction */ |
33 | |
34 | _exit(1); |
35 | } |
36 | |
37 | void setup_signal_handler(void) |
38 | { |
39 | struct sigaction signal_action; |
40 | |
41 | memset(&signal_action, 0, sizeof(signal_action)); |
42 | signal_action.sa_sigaction = signal_action_handler; |
43 | signal_action.sa_flags = SA_SIGINFO; |
44 | sigaction(SIGBUS, &signal_action, NULL); |
45 | } |
46 | |
47 | char cacheline_buf[128] __cacheline_aligned; |
48 | |
49 | int test_copy_first_unaligned(void) |
50 | { |
51 | /* Only run this test on a P9 or later */ |
52 | SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00)); |
53 | |
54 | /* Register our signal handler with SIGBUS */ |
55 | setup_signal_handler(); |
56 | |
57 | /* +1 makes buf unaligned */ |
58 | copy_first(cacheline_buf+1); |
59 | |
60 | /* We should not get here */ |
61 | return 1; |
62 | } |
63 | |
64 | int main(int argc, char *argv[]) |
65 | { |
66 | return test_harness(test_copy_first_unaligned, "test_copy_first_unaligned" ); |
67 | } |
68 | |