selftests/bpf: Test ldsx with more complex cases
[platform/kernel/linux-rpi.git] / tools / testing / selftests / bpf / progs / test_ldsx_insn.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
3
4 #include "vmlinux.h"
5 #include <bpf/bpf_helpers.h>
6 #include <bpf/bpf_tracing.h>
7
8 #if defined(__TARGET_ARCH_x86) && __clang_major__ >= 18
9 const volatile int skip = 0;
10 #else
11 const volatile int skip = 1;
12 #endif
13
14 volatile const short val1 = -1;
15 volatile const int val2 = -1;
16 short val3 = -1;
17 int val4 = -1;
18 int done1, done2, ret1, ret2;
19
20 SEC("?raw_tp/sys_enter")
21 int rdonly_map_prog(const void *ctx)
22 {
23         if (done1)
24                 return 0;
25
26         done1 = 1;
27         /* val1/val2 readonly map */
28         if (val1 == val2)
29                 ret1 = 1;
30         return 0;
31
32 }
33
34 SEC("?raw_tp/sys_enter")
35 int map_val_prog(const void *ctx)
36 {
37         if (done2)
38                 return 0;
39
40         done2 = 1;
41         /* val1/val2 regular read/write map */
42         if (val3 == val4)
43                 ret2 = 1;
44         return 0;
45
46 }
47
48 struct bpf_testmod_struct_arg_1 {
49         int a;
50 };
51
52 long long int_member;
53
54 SEC("?fentry/bpf_testmod_test_arg_ptr_to_struct")
55 int BPF_PROG2(test_ptr_struct_arg, struct bpf_testmod_struct_arg_1 *, p)
56 {
57         /* probed memory access */
58         int_member = p->a;
59         return 0;
60 }
61
62 long long set_optlen, set_retval;
63
64 SEC("?cgroup/getsockopt")
65 int _getsockopt(volatile struct bpf_sockopt *ctx)
66 {
67         int old_optlen, old_retval;
68
69         old_optlen = ctx->optlen;
70         old_retval = ctx->retval;
71
72         ctx->optlen = -1;
73         ctx->retval = -1;
74
75         /* sign extension for ctx member */
76         set_optlen = ctx->optlen;
77         set_retval = ctx->retval;
78
79         ctx->optlen = old_optlen;
80         ctx->retval = old_retval;
81
82         return 0;
83 }
84
85 long long set_mark;
86
87 SEC("?tc")
88 int _tc(volatile struct __sk_buff *skb)
89 {
90         long long tmp_mark;
91         int old_mark;
92
93         old_mark = skb->mark;
94
95         skb->mark = 0xf6fe;
96
97         /* narrowed sign extension for ctx member */
98 #if __clang_major__ >= 18
99         /* force narrow one-byte signed load. Otherwise, compiler may
100          * generate a 32-bit unsigned load followed by an s8 movsx.
101          */
102         asm volatile ("r1 = *(s8 *)(%[ctx] + %[off_mark])\n\t"
103                       "%[tmp_mark] = r1"
104                       : [tmp_mark]"=r"(tmp_mark)
105                       : [ctx]"r"(skb),
106                         [off_mark]"i"(offsetof(struct __sk_buff, mark))
107                       : "r1");
108 #else
109         tmp_mark = (char)skb->mark;
110 #endif
111         set_mark = tmp_mark;
112
113         skb->mark = old_mark;
114
115         return 0;
116 }
117
118 char _license[] SEC("license") = "GPL";