198d666d0SBrendan Jackman // SPDX-License-Identifier: GPL-2.0
298d666d0SBrendan Jackman #include <linux/bpf.h>
398d666d0SBrendan Jackman #include <bpf/bpf_helpers.h>
498d666d0SBrendan Jackman #include <bpf/bpf_tracing.h>
598d666d0SBrendan Jackman #include <stdbool.h>
698d666d0SBrendan Jackman 
798d666d0SBrendan Jackman #ifdef ENABLE_ATOMICS_TESTS
898d666d0SBrendan Jackman bool skip_tests __attribute((__section__(".data"))) = false;
998d666d0SBrendan Jackman #else
1098d666d0SBrendan Jackman bool skip_tests = true;
1198d666d0SBrendan Jackman #endif
1298d666d0SBrendan Jackman 
130f4feaccSYucong Sun __u32 pid = 0;
140f4feaccSYucong Sun 
1598d666d0SBrendan Jackman __u64 add64_value = 1;
1698d666d0SBrendan Jackman __u64 add64_result = 0;
1798d666d0SBrendan Jackman __u32 add32_value = 1;
1898d666d0SBrendan Jackman __u32 add32_result = 0;
1998d666d0SBrendan Jackman __u64 add_stack_value_copy = 0;
2098d666d0SBrendan Jackman __u64 add_stack_result = 0;
2198d666d0SBrendan Jackman __u64 add_noreturn_value = 1;
2298d666d0SBrendan Jackman 
23*07609c19SHou Tao SEC("raw_tp/sys_enter")
add(const void * ctx)24*07609c19SHou Tao int add(const void *ctx)
2598d666d0SBrendan Jackman {
260f4feaccSYucong Sun 	if (pid != (bpf_get_current_pid_tgid() >> 32))
270f4feaccSYucong Sun 		return 0;
2898d666d0SBrendan Jackman #ifdef ENABLE_ATOMICS_TESTS
2998d666d0SBrendan Jackman 	__u64 add_stack_value = 1;
3098d666d0SBrendan Jackman 
3198d666d0SBrendan Jackman 	add64_result = __sync_fetch_and_add(&add64_value, 2);
3298d666d0SBrendan Jackman 	add32_result = __sync_fetch_and_add(&add32_value, 2);
3398d666d0SBrendan Jackman 	add_stack_result = __sync_fetch_and_add(&add_stack_value, 2);
3498d666d0SBrendan Jackman 	add_stack_value_copy = add_stack_value;
3598d666d0SBrendan Jackman 	__sync_fetch_and_add(&add_noreturn_value, 2);
3698d666d0SBrendan Jackman #endif
3798d666d0SBrendan Jackman 
3898d666d0SBrendan Jackman 	return 0;
3998d666d0SBrendan Jackman }
4098d666d0SBrendan Jackman 
4198d666d0SBrendan Jackman __s64 sub64_value = 1;
4298d666d0SBrendan Jackman __s64 sub64_result = 0;
4398d666d0SBrendan Jackman __s32 sub32_value = 1;
4498d666d0SBrendan Jackman __s32 sub32_result = 0;
4598d666d0SBrendan Jackman __s64 sub_stack_value_copy = 0;
4698d666d0SBrendan Jackman __s64 sub_stack_result = 0;
4798d666d0SBrendan Jackman __s64 sub_noreturn_value = 1;
4898d666d0SBrendan Jackman 
49*07609c19SHou Tao SEC("raw_tp/sys_enter")
sub(const void * ctx)50*07609c19SHou Tao int sub(const void *ctx)
5198d666d0SBrendan Jackman {
520f4feaccSYucong Sun 	if (pid != (bpf_get_current_pid_tgid() >> 32))
530f4feaccSYucong Sun 		return 0;
5498d666d0SBrendan Jackman #ifdef ENABLE_ATOMICS_TESTS
5598d666d0SBrendan Jackman 	__u64 sub_stack_value = 1;
5698d666d0SBrendan Jackman 
5798d666d0SBrendan Jackman 	sub64_result = __sync_fetch_and_sub(&sub64_value, 2);
5898d666d0SBrendan Jackman 	sub32_result = __sync_fetch_and_sub(&sub32_value, 2);
5998d666d0SBrendan Jackman 	sub_stack_result = __sync_fetch_and_sub(&sub_stack_value, 2);
6098d666d0SBrendan Jackman 	sub_stack_value_copy = sub_stack_value;
6198d666d0SBrendan Jackman 	__sync_fetch_and_sub(&sub_noreturn_value, 2);
6298d666d0SBrendan Jackman #endif
6398d666d0SBrendan Jackman 
6498d666d0SBrendan Jackman 	return 0;
6598d666d0SBrendan Jackman }
6698d666d0SBrendan Jackman 
6798d666d0SBrendan Jackman __u64 and64_value = (0x110ull << 32);
6898d666d0SBrendan Jackman __u64 and64_result = 0;
6998d666d0SBrendan Jackman __u32 and32_value = 0x110;
7098d666d0SBrendan Jackman __u32 and32_result = 0;
7198d666d0SBrendan Jackman __u64 and_noreturn_value = (0x110ull << 32);
7298d666d0SBrendan Jackman 
73*07609c19SHou Tao SEC("raw_tp/sys_enter")
and(const void * ctx)74*07609c19SHou Tao int and(const void *ctx)
7598d666d0SBrendan Jackman {
760f4feaccSYucong Sun 	if (pid != (bpf_get_current_pid_tgid() >> 32))
770f4feaccSYucong Sun 		return 0;
7898d666d0SBrendan Jackman #ifdef ENABLE_ATOMICS_TESTS
7998d666d0SBrendan Jackman 
8098d666d0SBrendan Jackman 	and64_result = __sync_fetch_and_and(&and64_value, 0x011ull << 32);
8198d666d0SBrendan Jackman 	and32_result = __sync_fetch_and_and(&and32_value, 0x011);
8298d666d0SBrendan Jackman 	__sync_fetch_and_and(&and_noreturn_value, 0x011ull << 32);
8398d666d0SBrendan Jackman #endif
8498d666d0SBrendan Jackman 
8598d666d0SBrendan Jackman 	return 0;
8698d666d0SBrendan Jackman }
8798d666d0SBrendan Jackman 
8898d666d0SBrendan Jackman __u64 or64_value = (0x110ull << 32);
8998d666d0SBrendan Jackman __u64 or64_result = 0;
9098d666d0SBrendan Jackman __u32 or32_value = 0x110;
9198d666d0SBrendan Jackman __u32 or32_result = 0;
9298d666d0SBrendan Jackman __u64 or_noreturn_value = (0x110ull << 32);
9398d666d0SBrendan Jackman 
94*07609c19SHou Tao SEC("raw_tp/sys_enter")
or(const void * ctx)95*07609c19SHou Tao int or(const void *ctx)
9698d666d0SBrendan Jackman {
970f4feaccSYucong Sun 	if (pid != (bpf_get_current_pid_tgid() >> 32))
980f4feaccSYucong Sun 		return 0;
9998d666d0SBrendan Jackman #ifdef ENABLE_ATOMICS_TESTS
10098d666d0SBrendan Jackman 	or64_result = __sync_fetch_and_or(&or64_value, 0x011ull << 32);
10198d666d0SBrendan Jackman 	or32_result = __sync_fetch_and_or(&or32_value, 0x011);
10298d666d0SBrendan Jackman 	__sync_fetch_and_or(&or_noreturn_value, 0x011ull << 32);
10398d666d0SBrendan Jackman #endif
10498d666d0SBrendan Jackman 
10598d666d0SBrendan Jackman 	return 0;
10698d666d0SBrendan Jackman }
10798d666d0SBrendan Jackman 
10898d666d0SBrendan Jackman __u64 xor64_value = (0x110ull << 32);
10998d666d0SBrendan Jackman __u64 xor64_result = 0;
11098d666d0SBrendan Jackman __u32 xor32_value = 0x110;
11198d666d0SBrendan Jackman __u32 xor32_result = 0;
11298d666d0SBrendan Jackman __u64 xor_noreturn_value = (0x110ull << 32);
11398d666d0SBrendan Jackman 
114*07609c19SHou Tao SEC("raw_tp/sys_enter")
xor(const void * ctx)115*07609c19SHou Tao int xor(const void *ctx)
11698d666d0SBrendan Jackman {
1170f4feaccSYucong Sun 	if (pid != (bpf_get_current_pid_tgid() >> 32))
1180f4feaccSYucong Sun 		return 0;
11998d666d0SBrendan Jackman #ifdef ENABLE_ATOMICS_TESTS
12098d666d0SBrendan Jackman 	xor64_result = __sync_fetch_and_xor(&xor64_value, 0x011ull << 32);
12198d666d0SBrendan Jackman 	xor32_result = __sync_fetch_and_xor(&xor32_value, 0x011);
12298d666d0SBrendan Jackman 	__sync_fetch_and_xor(&xor_noreturn_value, 0x011ull << 32);
12398d666d0SBrendan Jackman #endif
12498d666d0SBrendan Jackman 
12598d666d0SBrendan Jackman 	return 0;
12698d666d0SBrendan Jackman }
12798d666d0SBrendan Jackman 
12898d666d0SBrendan Jackman __u64 cmpxchg64_value = 1;
12998d666d0SBrendan Jackman __u64 cmpxchg64_result_fail = 0;
13098d666d0SBrendan Jackman __u64 cmpxchg64_result_succeed = 0;
13198d666d0SBrendan Jackman __u32 cmpxchg32_value = 1;
13298d666d0SBrendan Jackman __u32 cmpxchg32_result_fail = 0;
13398d666d0SBrendan Jackman __u32 cmpxchg32_result_succeed = 0;
13498d666d0SBrendan Jackman 
135*07609c19SHou Tao SEC("raw_tp/sys_enter")
cmpxchg(const void * ctx)136*07609c19SHou Tao int cmpxchg(const void *ctx)
13798d666d0SBrendan Jackman {
1380f4feaccSYucong Sun 	if (pid != (bpf_get_current_pid_tgid() >> 32))
1390f4feaccSYucong Sun 		return 0;
14098d666d0SBrendan Jackman #ifdef ENABLE_ATOMICS_TESTS
14198d666d0SBrendan Jackman 	cmpxchg64_result_fail = __sync_val_compare_and_swap(&cmpxchg64_value, 0, 3);
14298d666d0SBrendan Jackman 	cmpxchg64_result_succeed = __sync_val_compare_and_swap(&cmpxchg64_value, 1, 2);
14398d666d0SBrendan Jackman 
14498d666d0SBrendan Jackman 	cmpxchg32_result_fail = __sync_val_compare_and_swap(&cmpxchg32_value, 0, 3);
14598d666d0SBrendan Jackman 	cmpxchg32_result_succeed = __sync_val_compare_and_swap(&cmpxchg32_value, 1, 2);
14698d666d0SBrendan Jackman #endif
14798d666d0SBrendan Jackman 
14898d666d0SBrendan Jackman 	return 0;
14998d666d0SBrendan Jackman }
15098d666d0SBrendan Jackman 
15198d666d0SBrendan Jackman __u64 xchg64_value = 1;
15298d666d0SBrendan Jackman __u64 xchg64_result = 0;
15398d666d0SBrendan Jackman __u32 xchg32_value = 1;
15498d666d0SBrendan Jackman __u32 xchg32_result = 0;
15598d666d0SBrendan Jackman 
156*07609c19SHou Tao SEC("raw_tp/sys_enter")
xchg(const void * ctx)157*07609c19SHou Tao int xchg(const void *ctx)
15898d666d0SBrendan Jackman {
1590f4feaccSYucong Sun 	if (pid != (bpf_get_current_pid_tgid() >> 32))
1600f4feaccSYucong Sun 		return 0;
16198d666d0SBrendan Jackman #ifdef ENABLE_ATOMICS_TESTS
16298d666d0SBrendan Jackman 	__u64 val64 = 2;
16398d666d0SBrendan Jackman 	__u32 val32 = 2;
16498d666d0SBrendan Jackman 
16598d666d0SBrendan Jackman 	xchg64_result = __sync_lock_test_and_set(&xchg64_value, val64);
16698d666d0SBrendan Jackman 	xchg32_result = __sync_lock_test_and_set(&xchg32_value, val32);
16798d666d0SBrendan Jackman #endif
16898d666d0SBrendan Jackman 
16998d666d0SBrendan Jackman 	return 0;
17098d666d0SBrendan Jackman }
171