File Index
Files and directories
Sign in
FILE

preempt_lock.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/progs/preempt_lock.c 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
  8extern int bpf_copy_from_user_str(void *dst, u32 dst__sz, const void *unsafe_ptr__ign, u64 flags) __weak __ksym;
  9
 10SEC("?tc")
 11__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
 12int preempt_lock_missing_1(struct __sk_buff *ctx)
 13{
 14	bpf_preempt_disable();
 15	return 0;
 16}
 17
 18SEC("?tc")
 19__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
 20int preempt_lock_missing_2(struct __sk_buff *ctx)
 21{
 22	bpf_preempt_disable();
 23	bpf_preempt_disable();
 24	return 0;
 25}
 26
 27SEC("?tc")
 28__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
 29int 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
 37SEC("?tc")
 38__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
 39int 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
 49static __noinline void preempt_disable(void)
 50{
 51	bpf_preempt_disable();
 52}
 53
 54static __noinline void preempt_enable(void)
 55{
 56	bpf_preempt_enable();
 57}
 58
 59SEC("?tc")
 60__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
 61int preempt_lock_missing_1_subprog(struct __sk_buff *ctx)
 62{
 63	preempt_disable();
 64	return 0;
 65}
 66
 67SEC("?tc")
 68__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
 69int preempt_lock_missing_2_subprog(struct __sk_buff *ctx)
 70{
 71	preempt_disable();
 72	preempt_disable();
 73	return 0;
 74}
 75
 76SEC("?tc")
 77__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region")
 78int 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
 86static __noinline void preempt_balance_subprog(void)
 87{
 88	preempt_disable();
 89	preempt_enable();
 90}
 91
 92SEC("?tc")
 93__success int preempt_balance(struct __sk_buff *ctx)
 94{
 95	bpf_guard_preempt();
 96	return 0;
 97}
 98
 99SEC("?tc")
100__success int preempt_balance_subprog_test(struct __sk_buff *ctx)
101{
102	preempt_balance_subprog();
103	return 0;
104}
105
106SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
107__failure __msg("sleepable helper bpf_copy_from_user#")
108int 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
118SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
119__failure __msg("kernel func bpf_copy_from_user_str is sleepable within non-preemptible region")
120int 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
130int __noinline preempt_global_subprog(void)
131{
132	preempt_balance_subprog();
133	return 0;
134}
135
136SEC("?tc")
137__success
138int preempt_global_subprog_test(struct __sk_buff *ctx)
139{
140	preempt_disable();
141	preempt_global_subprog();
142	preempt_enable();
143	return 0;
144}
145
146int __noinline
147global_subprog(int i)
148{
149	if (i)
150		bpf_printk("%p", &i);
151	return i;
152}
153
154int __noinline
155global_sleepable_helper_subprog(int i)
156{
157	if (i)
158		bpf_copy_from_user(&i, sizeof(i), NULL);
159	return i;
160}
161
162int __noinline
163global_sleepable_kfunc_subprog(int i)
164{
165	if (i)
166		bpf_copy_from_user_str(&i, sizeof(i), NULL, 0);
167	global_subprog(i);
168	return i;
169}
170
171int __noinline
172global_subprog_calling_sleepable_global(int i)
173{
174	if (!i)
175		global_sleepable_kfunc_subprog(i);
176	return i;
177}
178
179SEC("?syscall")
180__failure __msg("global functions that may sleep are not allowed in non-sleepable context")
181int preempt_global_sleepable_helper_subprog(struct __sk_buff *ctx)
182{
183	preempt_disable();
184	if (ctx->mark)
185		global_sleepable_helper_subprog(ctx->mark);
186	preempt_enable();
187	return 0;
188}
189
190SEC("?syscall")
191__failure __msg("global functions that may sleep are not allowed in non-sleepable context")
192int preempt_global_sleepable_kfunc_subprog(struct __sk_buff *ctx)
193{
194	preempt_disable();
195	if (ctx->mark)
196		global_sleepable_kfunc_subprog(ctx->mark);
197	preempt_enable();
198	return 0;
199}
200
201SEC("?syscall")
202__failure __msg("global functions that may sleep are not allowed in non-sleepable context")
203int preempt_global_sleepable_subprog_indirect(struct __sk_buff *ctx)
204{
205	preempt_disable();
206	if (ctx->mark)
207		global_subprog_calling_sleepable_global(ctx->mark);
208	preempt_enable();
209	return 0;
210}
211
212char _license[] SEC("license") = "GPL";
~/ Read-only file preview.