1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/bpf.h> |
3 | #include <bpf/bpf_helpers.h> |
4 | #include <bpf/bpf_tracing.h> |
5 | #include <stdbool.h> |
6 | |
7 | #ifdef ENABLE_ATOMICS_TESTS |
8 | bool skip_tests __attribute((__section__(".data" ))) = false; |
9 | #else |
10 | bool skip_tests = true; |
11 | #endif |
12 | |
13 | __u32 pid = 0; |
14 | |
15 | __u64 add64_value = 1; |
16 | __u64 add64_result = 0; |
17 | __u32 add32_value = 1; |
18 | __u32 add32_result = 0; |
19 | __u64 add_stack_value_copy = 0; |
20 | __u64 add_stack_result = 0; |
21 | __u64 add_noreturn_value = 1; |
22 | |
23 | SEC("raw_tp/sys_enter" ) |
24 | int add(const void *ctx) |
25 | { |
26 | if (pid != (bpf_get_current_pid_tgid() >> 32)) |
27 | return 0; |
28 | #ifdef ENABLE_ATOMICS_TESTS |
29 | __u64 add_stack_value = 1; |
30 | |
31 | add64_result = __sync_fetch_and_add(&add64_value, 2); |
32 | add32_result = __sync_fetch_and_add(&add32_value, 2); |
33 | add_stack_result = __sync_fetch_and_add(&add_stack_value, 2); |
34 | add_stack_value_copy = add_stack_value; |
35 | __sync_fetch_and_add(&add_noreturn_value, 2); |
36 | #endif |
37 | |
38 | return 0; |
39 | } |
40 | |
41 | __s64 sub64_value = 1; |
42 | __s64 sub64_result = 0; |
43 | __s32 sub32_value = 1; |
44 | __s32 sub32_result = 0; |
45 | __s64 sub_stack_value_copy = 0; |
46 | __s64 sub_stack_result = 0; |
47 | __s64 sub_noreturn_value = 1; |
48 | |
49 | SEC("raw_tp/sys_enter" ) |
50 | int sub(const void *ctx) |
51 | { |
52 | if (pid != (bpf_get_current_pid_tgid() >> 32)) |
53 | return 0; |
54 | #ifdef ENABLE_ATOMICS_TESTS |
55 | __u64 sub_stack_value = 1; |
56 | |
57 | sub64_result = __sync_fetch_and_sub(&sub64_value, 2); |
58 | sub32_result = __sync_fetch_and_sub(&sub32_value, 2); |
59 | sub_stack_result = __sync_fetch_and_sub(&sub_stack_value, 2); |
60 | sub_stack_value_copy = sub_stack_value; |
61 | __sync_fetch_and_sub(&sub_noreturn_value, 2); |
62 | #endif |
63 | |
64 | return 0; |
65 | } |
66 | |
67 | __u64 and64_value = (0x110ull << 32); |
68 | __u64 and64_result = 0; |
69 | __u32 and32_value = 0x110; |
70 | __u32 and32_result = 0; |
71 | __u64 and_noreturn_value = (0x110ull << 32); |
72 | |
73 | SEC("raw_tp/sys_enter" ) |
74 | int and(const void *ctx) |
75 | { |
76 | if (pid != (bpf_get_current_pid_tgid() >> 32)) |
77 | return 0; |
78 | #ifdef ENABLE_ATOMICS_TESTS |
79 | |
80 | and64_result = __sync_fetch_and_and(&and64_value, 0x011ull << 32); |
81 | and32_result = __sync_fetch_and_and(&and32_value, 0x011); |
82 | __sync_fetch_and_and(&and_noreturn_value, 0x011ull << 32); |
83 | #endif |
84 | |
85 | return 0; |
86 | } |
87 | |
88 | __u64 or64_value = (0x110ull << 32); |
89 | __u64 or64_result = 0; |
90 | __u32 or32_value = 0x110; |
91 | __u32 or32_result = 0; |
92 | __u64 or_noreturn_value = (0x110ull << 32); |
93 | |
94 | SEC("raw_tp/sys_enter" ) |
95 | int or(const void *ctx) |
96 | { |
97 | if (pid != (bpf_get_current_pid_tgid() >> 32)) |
98 | return 0; |
99 | #ifdef ENABLE_ATOMICS_TESTS |
100 | or64_result = __sync_fetch_and_or(&or64_value, 0x011ull << 32); |
101 | or32_result = __sync_fetch_and_or(&or32_value, 0x011); |
102 | __sync_fetch_and_or(&or_noreturn_value, 0x011ull << 32); |
103 | #endif |
104 | |
105 | return 0; |
106 | } |
107 | |
108 | __u64 xor64_value = (0x110ull << 32); |
109 | __u64 xor64_result = 0; |
110 | __u32 xor32_value = 0x110; |
111 | __u32 xor32_result = 0; |
112 | __u64 xor_noreturn_value = (0x110ull << 32); |
113 | |
114 | SEC("raw_tp/sys_enter" ) |
115 | int xor(const void *ctx) |
116 | { |
117 | if (pid != (bpf_get_current_pid_tgid() >> 32)) |
118 | return 0; |
119 | #ifdef ENABLE_ATOMICS_TESTS |
120 | xor64_result = __sync_fetch_and_xor(&xor64_value, 0x011ull << 32); |
121 | xor32_result = __sync_fetch_and_xor(&xor32_value, 0x011); |
122 | __sync_fetch_and_xor(&xor_noreturn_value, 0x011ull << 32); |
123 | #endif |
124 | |
125 | return 0; |
126 | } |
127 | |
128 | __u64 cmpxchg64_value = 1; |
129 | __u64 cmpxchg64_result_fail = 0; |
130 | __u64 cmpxchg64_result_succeed = 0; |
131 | __u32 cmpxchg32_value = 1; |
132 | __u32 cmpxchg32_result_fail = 0; |
133 | __u32 cmpxchg32_result_succeed = 0; |
134 | |
135 | SEC("raw_tp/sys_enter" ) |
136 | int cmpxchg(const void *ctx) |
137 | { |
138 | if (pid != (bpf_get_current_pid_tgid() >> 32)) |
139 | return 0; |
140 | #ifdef ENABLE_ATOMICS_TESTS |
141 | cmpxchg64_result_fail = __sync_val_compare_and_swap(&cmpxchg64_value, 0, 3); |
142 | cmpxchg64_result_succeed = __sync_val_compare_and_swap(&cmpxchg64_value, 1, 2); |
143 | |
144 | cmpxchg32_result_fail = __sync_val_compare_and_swap(&cmpxchg32_value, 0, 3); |
145 | cmpxchg32_result_succeed = __sync_val_compare_and_swap(&cmpxchg32_value, 1, 2); |
146 | #endif |
147 | |
148 | return 0; |
149 | } |
150 | |
151 | __u64 xchg64_value = 1; |
152 | __u64 xchg64_result = 0; |
153 | __u32 xchg32_value = 1; |
154 | __u32 xchg32_result = 0; |
155 | |
156 | SEC("raw_tp/sys_enter" ) |
157 | int xchg(const void *ctx) |
158 | { |
159 | if (pid != (bpf_get_current_pid_tgid() >> 32)) |
160 | return 0; |
161 | #ifdef ENABLE_ATOMICS_TESTS |
162 | __u64 val64 = 2; |
163 | __u32 val32 = 2; |
164 | |
165 | xchg64_result = __sync_lock_test_and_set(&xchg64_value, val64); |
166 | xchg32_result = __sync_lock_test_and_set(&xchg32_value, val32); |
167 | #endif |
168 | |
169 | return 0; |
170 | } |
171 | |