1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2024 Yafang Shao <laoar.shao@gmail.com> */ 3 4 #include "vmlinux.h" 5 #include <bpf/bpf_helpers.h> 6 #include <bpf/bpf_tracing.h> 7 8 #include "bpf_misc.h" 9 #include "task_kfunc_common.h" 10 11 char _license[] SEC("license") = "GPL"; 12 13 int bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, 14 u32 nr_bits) __ksym __weak; 15 int *bpf_iter_bits_next(struct bpf_iter_bits *it) __ksym __weak; 16 void bpf_iter_bits_destroy(struct bpf_iter_bits *it) __ksym __weak; 17 18 SEC("iter.s/cgroup") 19 __description("bits iter without destroy") 20 __failure __msg("Unreleased reference") 21 int BPF_PROG(no_destroy, struct bpf_iter_meta *meta, struct cgroup *cgrp) 22 { 23 struct bpf_iter_bits it; 24 u64 data = 1; 25 26 bpf_iter_bits_new(&it, &data, 1); 27 bpf_iter_bits_next(&it); 28 return 0; 29 } 30 31 SEC("iter/cgroup") 32 __description("uninitialized iter in ->next()") 33 __failure __msg("expected an initialized iter_bits as arg #1") 34 int BPF_PROG(next_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp) 35 { 36 struct bpf_iter_bits *it = NULL; 37 38 bpf_iter_bits_next(it); 39 return 0; 40 } 41 42 SEC("iter/cgroup") 43 __description("uninitialized iter in ->destroy()") 44 __failure __msg("expected an initialized iter_bits as arg #1") 45 int BPF_PROG(destroy_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp) 46 { 47 struct bpf_iter_bits it = {}; 48 49 bpf_iter_bits_destroy(&it); 50 return 0; 51 } 52 53 SEC("syscall") 54 __description("null pointer") 55 __success __retval(0) 56 int null_pointer(void) 57 { 58 int nr = 0; 59 int *bit; 60 61 bpf_for_each(bits, bit, NULL, 1) 62 nr++; 63 return nr; 64 } 65 66 SEC("syscall") 67 __description("bits copy") 68 __success __retval(10) 69 int bits_copy(void) 70 { 71 u64 data = 0xf7310UL; /* 4 + 3 + 2 + 1 + 0*/ 72 int nr = 0; 73 int *bit; 74 75 bpf_for_each(bits, bit, &data, 1) 76 nr++; 77 return nr; 78 } 79 80 SEC("syscall") 81 __description("bits memalloc") 82 __success __retval(64) 83 int bits_memalloc(void) 84 { 85 u64 data[2]; 86 int nr = 0; 87 int *bit; 88 89 __builtin_memset(&data, 0xf0, sizeof(data)); /* 4 * 16 */ 90 bpf_for_each(bits, bit, &data[0], sizeof(data) / sizeof(u64)) 91 nr++; 92 return nr; 93 } 94 95 SEC("syscall") 96 __description("bit index") 97 __success __retval(8) 98 int bit_index(void) 99 { 100 u64 data = 0x100; 101 int bit_idx = 0; 102 int *bit; 103 104 bpf_for_each(bits, bit, &data, 1) { 105 if (*bit == 0) 106 continue; 107 bit_idx = *bit; 108 } 109 return bit_idx; 110 } 111 112 SEC("syscall") 113 __description("bits nomem") 114 __success __retval(0) 115 int bits_nomem(void) 116 { 117 u64 data[4]; 118 int nr = 0; 119 int *bit; 120 121 __builtin_memset(&data, 0xff, sizeof(data)); 122 bpf_for_each(bits, bit, &data[0], 513) /* Be greater than 512 */ 123 nr++; 124 return nr; 125 } 126 127 SEC("syscall") 128 __description("fewer words") 129 __success __retval(1) 130 int fewer_words(void) 131 { 132 u64 data[2] = {0x1, 0xff}; 133 int nr = 0; 134 int *bit; 135 136 bpf_for_each(bits, bit, &data[0], 1) 137 nr++; 138 return nr; 139 } 140 141 SEC("syscall") 142 __description("zero words") 143 __success __retval(0) 144 int zero_words(void) 145 { 146 u64 data[2] = {0x1, 0xff}; 147 int nr = 0; 148 int *bit; 149 150 bpf_for_each(bits, bit, &data[0], 0) 151 nr++; 152 return nr; 153 } 154