]> Git Repo - linux.git/blob - tools/testing/selftests/bpf/progs/preempt_lock.c
Linux 6.14-rc3
[linux.git] / tools / testing / selftests / bpf / progs / preempt_lock.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <vmlinux.h>
3 #include <bpf/bpf_helpers.h>
4 #include <bpf/bpf_tracing.h>
5 #include "bpf_misc.h"
6 #include "bpf_experimental.h"
7
8 extern int bpf_copy_from_user_str(void *dst, u32 dst__sz, const void *unsafe_ptr__ign, u64 flags) __weak __ksym;
9
10 SEC("?tc")
11 __failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
12 int preempt_lock_missing_1(struct __sk_buff *ctx)
13 {
14         bpf_preempt_disable();
15         return 0;
16 }
17
18 SEC("?tc")
19 __failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
20 int preempt_lock_missing_2(struct __sk_buff *ctx)
21 {
22         bpf_preempt_disable();
23         bpf_preempt_disable();
24         return 0;
25 }
26
27 SEC("?tc")
28 __failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
29 int preempt_lock_missing_3(struct __sk_buff *ctx)
30 {
31         bpf_preempt_disable();
32         bpf_preempt_disable();
33         bpf_preempt_disable();
34         return 0;
35 }
36
37 SEC("?tc")
38 __failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
39 int preempt_lock_missing_3_minus_2(struct __sk_buff *ctx)
40 {
41         bpf_preempt_disable();
42         bpf_preempt_disable();
43         bpf_preempt_disable();
44         bpf_preempt_enable();
45         bpf_preempt_enable();
46         return 0;
47 }
48
49 static __noinline void preempt_disable(void)
50 {
51         bpf_preempt_disable();
52 }
53
54 static __noinline void preempt_enable(void)
55 {
56         bpf_preempt_enable();
57 }
58
59 SEC("?tc")
60 __failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
61 int preempt_lock_missing_1_subprog(struct __sk_buff *ctx)
62 {
63         preempt_disable();
64         return 0;
65 }
66
67 SEC("?tc")
68 __failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
69 int preempt_lock_missing_2_subprog(struct __sk_buff *ctx)
70 {
71         preempt_disable();
72         preempt_disable();
73         return 0;
74 }
75
76 SEC("?tc")
77 __failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
78 int preempt_lock_missing_2_minus_1_subprog(struct __sk_buff *ctx)
79 {
80         preempt_disable();
81         preempt_disable();
82         preempt_enable();
83         return 0;
84 }
85
86 static __noinline void preempt_balance_subprog(void)
87 {
88         preempt_disable();
89         preempt_enable();
90 }
91
92 SEC("?tc")
93 __success int preempt_balance(struct __sk_buff *ctx)
94 {
95         bpf_guard_preempt();
96         return 0;
97 }
98
99 SEC("?tc")
100 __success int preempt_balance_subprog_test(struct __sk_buff *ctx)
101 {
102         preempt_balance_subprog();
103         return 0;
104 }
105
106 SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
107 __failure __msg("sleepable helper bpf_copy_from_user#")
108 int preempt_sleepable_helper(void *ctx)
109 {
110         u32 data;
111
112         bpf_preempt_disable();
113         bpf_copy_from_user(&data, sizeof(data), NULL);
114         bpf_preempt_enable();
115         return 0;
116 }
117
118 SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
119 __failure __msg("kernel func bpf_copy_from_user_str is sleepable within non-preemptible region")
120 int preempt_sleepable_kfunc(void *ctx)
121 {
122         u32 data;
123
124         bpf_preempt_disable();
125         bpf_copy_from_user_str(&data, sizeof(data), NULL, 0);
126         bpf_preempt_enable();
127         return 0;
128 }
129
130 int __noinline preempt_global_subprog(void)
131 {
132         preempt_balance_subprog();
133         return 0;
134 }
135
136 SEC("?tc")
137 __failure __msg("global function calls are not allowed with preemption disabled")
138 int preempt_global_subprog_test(struct __sk_buff *ctx)
139 {
140         preempt_disable();
141         preempt_global_subprog();
142         preempt_enable();
143         return 0;
144 }
145
146 char _license[] SEC("license") = "GPL";
This page took 0.039197 seconds and 4 git commands to generate.