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 8SEC("?tc") 9__failure __msg("1 bpf_preempt_enable is missing") 10int preempt_lock_missing_1(struct __sk_buff *ctx) 11{ 12 bpf_preempt_disable(); 13 return 0; 14} 15 16SEC("?tc") 17__failure __msg("2 bpf_preempt_enable(s) are missing") 18int preempt_lock_missing_2(struct __sk_buff *ctx) 19{ 20 bpf_preempt_disable(); 21 bpf_preempt_disable(); 22 return 0; 23} 24 25SEC("?tc") 26__failure __msg("3 bpf_preempt_enable(s) are missing") 27int preempt_lock_missing_3(struct __sk_buff *ctx) 28{ 29 bpf_preempt_disable(); 30 bpf_preempt_disable(); 31 bpf_preempt_disable(); 32 return 0; 33} 34 35SEC("?tc") 36__failure __msg("1 bpf_preempt_enable is missing") 37int preempt_lock_missing_3_minus_2(struct __sk_buff *ctx) 38{ 39 bpf_preempt_disable(); 40 bpf_preempt_disable(); 41 bpf_preempt_disable(); 42 bpf_preempt_enable(); 43 bpf_preempt_enable(); 44 return 0; 45} 46 47static __noinline void preempt_disable(void) 48{ 49 bpf_preempt_disable(); 50} 51 52static __noinline void preempt_enable(void) 53{ 54 bpf_preempt_enable(); 55} 56 57SEC("?tc") 58__failure __msg("1 bpf_preempt_enable is missing") 59int preempt_lock_missing_1_subprog(struct __sk_buff *ctx) 60{ 61 preempt_disable(); 62 return 0; 63} 64 65SEC("?tc") 66__failure __msg("2 bpf_preempt_enable(s) are missing") 67int preempt_lock_missing_2_subprog(struct __sk_buff *ctx) 68{ 69 preempt_disable(); 70 preempt_disable(); 71 return 0; 72} 73 74SEC("?tc") 75__failure __msg("1 bpf_preempt_enable is missing") 76int preempt_lock_missing_2_minus_1_subprog(struct __sk_buff *ctx) 77{ 78 preempt_disable(); 79 preempt_disable(); 80 preempt_enable(); 81 return 0; 82} 83 84static __noinline void preempt_balance_subprog(void) 85{ 86 preempt_disable(); 87 preempt_enable(); 88} 89 90SEC("?tc") 91__success int preempt_balance(struct __sk_buff *ctx) 92{ 93 bpf_guard_preempt(); 94 return 0; 95} 96 97SEC("?tc") 98__success int preempt_balance_subprog_test(struct __sk_buff *ctx) 99{ 100 preempt_balance_subprog(); 101 return 0; 102} 103 104SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") 105__failure __msg("sleepable helper bpf_copy_from_user#") 106int preempt_sleepable_helper(void *ctx) 107{ 108 u32 data; 109 110 bpf_preempt_disable(); 111 bpf_copy_from_user(&data, sizeof(data), NULL); 112 bpf_preempt_enable(); 113 return 0; 114} 115 116int __noinline preempt_global_subprog(void) 117{ 118 preempt_balance_subprog(); 119 return 0; 120} 121 122SEC("?tc") 123__failure __msg("global function calls are not allowed with preemption disabled") 124int preempt_global_subprog_test(struct __sk_buff *ctx) 125{ 126 preempt_disable(); 127 preempt_global_subprog(); 128 preempt_enable(); 129 return 0; 130} 131 132char _license[] SEC("license") = "GPL"; 133