FILE
preempt_lock.c
File preview with syntax highlighting.
linux-6.19.14/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 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.