10c606571SYonghong Song // SPDX-License-Identifier: GPL-2.0
20c606571SYonghong Song /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
30c606571SYonghong Song 
40c606571SYonghong Song #include "vmlinux.h"
50c606571SYonghong Song #include <bpf/bpf_helpers.h>
60c606571SYonghong Song #include <bpf/bpf_tracing.h>
70c606571SYonghong Song 
8*0209fd51SPu Lehui #if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \
9*0209fd51SPu Lehui      (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && __clang_major__ >= 18
100c606571SYonghong Song const volatile int skip = 0;
110c606571SYonghong Song #else
120c606571SYonghong Song const volatile int skip = 1;
130c606571SYonghong Song #endif
140c606571SYonghong Song 
150c606571SYonghong Song volatile const short val1 = -1;
160c606571SYonghong Song volatile const int val2 = -1;
170c606571SYonghong Song short val3 = -1;
180c606571SYonghong Song int val4 = -1;
190c606571SYonghong Song int done1, done2, ret1, ret2;
200c606571SYonghong Song 
210c606571SYonghong Song SEC("?raw_tp/sys_enter")
rdonly_map_prog(const void * ctx)220c606571SYonghong Song int rdonly_map_prog(const void *ctx)
230c606571SYonghong Song {
240c606571SYonghong Song 	if (done1)
250c606571SYonghong Song 		return 0;
260c606571SYonghong Song 
270c606571SYonghong Song 	done1 = 1;
280c606571SYonghong Song 	/* val1/val2 readonly map */
290c606571SYonghong Song 	if (val1 == val2)
300c606571SYonghong Song 		ret1 = 1;
310c606571SYonghong Song 	return 0;
320c606571SYonghong Song 
330c606571SYonghong Song }
340c606571SYonghong Song 
350c606571SYonghong Song SEC("?raw_tp/sys_enter")
map_val_prog(const void * ctx)360c606571SYonghong Song int map_val_prog(const void *ctx)
370c606571SYonghong Song {
380c606571SYonghong Song 	if (done2)
390c606571SYonghong Song 		return 0;
400c606571SYonghong Song 
410c606571SYonghong Song 	done2 = 1;
420c606571SYonghong Song 	/* val1/val2 regular read/write map */
430c606571SYonghong Song 	if (val3 == val4)
440c606571SYonghong Song 		ret2 = 1;
450c606571SYonghong Song 	return 0;
460c606571SYonghong Song 
470c606571SYonghong Song }
480c606571SYonghong Song 
490c606571SYonghong Song struct bpf_testmod_struct_arg_1 {
500c606571SYonghong Song 	int a;
510c606571SYonghong Song };
520c606571SYonghong Song 
530c606571SYonghong Song long long int_member;
540c606571SYonghong Song 
550c606571SYonghong Song SEC("?fentry/bpf_testmod_test_arg_ptr_to_struct")
BPF_PROG2(test_ptr_struct_arg,struct bpf_testmod_struct_arg_1 *,p)560c606571SYonghong Song int BPF_PROG2(test_ptr_struct_arg, struct bpf_testmod_struct_arg_1 *, p)
570c606571SYonghong Song {
580c606571SYonghong Song 	/* probed memory access */
590c606571SYonghong Song 	int_member = p->a;
600c606571SYonghong Song         return 0;
610c606571SYonghong Song }
620c606571SYonghong Song 
630c606571SYonghong Song long long set_optlen, set_retval;
640c606571SYonghong Song 
650c606571SYonghong Song SEC("?cgroup/getsockopt")
_getsockopt(volatile struct bpf_sockopt * ctx)660c606571SYonghong Song int _getsockopt(volatile struct bpf_sockopt *ctx)
670c606571SYonghong Song {
680c606571SYonghong Song 	int old_optlen, old_retval;
690c606571SYonghong Song 
700c606571SYonghong Song 	old_optlen = ctx->optlen;
710c606571SYonghong Song 	old_retval = ctx->retval;
720c606571SYonghong Song 
730c606571SYonghong Song 	ctx->optlen = -1;
740c606571SYonghong Song 	ctx->retval = -1;
750c606571SYonghong Song 
760c606571SYonghong Song 	/* sign extension for ctx member */
770c606571SYonghong Song 	set_optlen = ctx->optlen;
780c606571SYonghong Song 	set_retval = ctx->retval;
790c606571SYonghong Song 
800c606571SYonghong Song 	ctx->optlen = old_optlen;
810c606571SYonghong Song 	ctx->retval = old_retval;
820c606571SYonghong Song 
830c606571SYonghong Song 	return 0;
840c606571SYonghong Song }
850c606571SYonghong Song 
860c606571SYonghong Song long long set_mark;
870c606571SYonghong Song 
880c606571SYonghong Song SEC("?tc")
_tc(volatile struct __sk_buff * skb)890c606571SYonghong Song int _tc(volatile struct __sk_buff *skb)
900c606571SYonghong Song {
910c606571SYonghong Song 	long long tmp_mark;
920c606571SYonghong Song 	int old_mark;
930c606571SYonghong Song 
940c606571SYonghong Song 	old_mark = skb->mark;
950c606571SYonghong Song 
960c606571SYonghong Song 	skb->mark = 0xf6fe;
970c606571SYonghong Song 
980c606571SYonghong Song 	/* narrowed sign extension for ctx member */
990c606571SYonghong Song #if __clang_major__ >= 18
1000c606571SYonghong Song 	/* force narrow one-byte signed load. Otherwise, compiler may
1010c606571SYonghong Song 	 * generate a 32-bit unsigned load followed by an s8 movsx.
1020c606571SYonghong Song 	 */
1030c606571SYonghong Song 	asm volatile ("r1 = *(s8 *)(%[ctx] + %[off_mark])\n\t"
1040c606571SYonghong Song 		      "%[tmp_mark] = r1"
1050c606571SYonghong Song 		      : [tmp_mark]"=r"(tmp_mark)
1060c606571SYonghong Song 		      : [ctx]"r"(skb),
1070c606571SYonghong Song 			[off_mark]"i"(offsetof(struct __sk_buff, mark))
1080c606571SYonghong Song 		      : "r1");
1090c606571SYonghong Song #else
1100c606571SYonghong Song 	tmp_mark = (char)skb->mark;
1110c606571SYonghong Song #endif
1120c606571SYonghong Song 	set_mark = tmp_mark;
1130c606571SYonghong Song 
1140c606571SYonghong Song 	skb->mark = old_mark;
1150c606571SYonghong Song 
1160c606571SYonghong Song 	return 0;
1170c606571SYonghong Song }
1180c606571SYonghong Song 
1190c606571SYonghong Song char _license[] SEC("license") = "GPL";
120