Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  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
 11char _license[] SEC("license") = "GPL";
 12
 13int bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign,
 14		      u32 nr_bits) __ksym __weak;
 15int *bpf_iter_bits_next(struct bpf_iter_bits *it) __ksym __weak;
 16void bpf_iter_bits_destroy(struct bpf_iter_bits *it) __ksym __weak;
 17
 18u64 bits_array[511] = {};
 19
 20SEC("iter.s/cgroup")
 21__description("bits iter without destroy")
 22__failure __msg("Unreleased reference")
 23int BPF_PROG(no_destroy, struct bpf_iter_meta *meta, struct cgroup *cgrp)
 24{
 25	struct bpf_iter_bits it;
 26	u64 data = 1;
 27
 28	bpf_iter_bits_new(&it, &data, 1);
 29	bpf_iter_bits_next(&it);
 30	return 0;
 31}
 32
 33SEC("iter/cgroup")
 34__description("uninitialized iter in ->next()")
 35__failure __msg("expected an initialized iter_bits as arg #0")
 36int BPF_PROG(next_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp)
 37{
 38	struct bpf_iter_bits it = {};
 39
 40	bpf_iter_bits_next(&it);
 41	return 0;
 42}
 43
 44SEC("iter/cgroup")
 45__description("uninitialized iter in ->destroy()")
 46__failure __msg("expected an initialized iter_bits as arg #0")
 47int BPF_PROG(destroy_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp)
 48{
 49	struct bpf_iter_bits it = {};
 50
 51	bpf_iter_bits_destroy(&it);
 52	return 0;
 53}
 54
 55SEC("syscall")
 56__description("null pointer")
 57__success __retval(0)
 58int null_pointer(void)
 59{
 60	struct bpf_iter_bits iter;
 61	int err, nr = 0;
 62	int *bit;
 63
 64	err = bpf_iter_bits_new(&iter, NULL, 1);
 65	bpf_iter_bits_destroy(&iter);
 66	if (err != -EINVAL)
 67		return 1;
 68
 69	bpf_for_each(bits, bit, NULL, 1)
 70		nr++;
 71	return nr;
 72}
 73
 74SEC("syscall")
 75__description("bits copy")
 76__success __retval(10)
 77int bits_copy(void)
 78{
 79	u64 data = 0xf7310UL; /* 4 + 3 + 2 + 1 + 0*/
 80	int nr = 0;
 81	int *bit;
 82
 83	bpf_for_each(bits, bit, &data, 1)
 84		nr++;
 85	return nr;
 86}
 87
 88SEC("syscall")
 89__description("bits memalloc")
 90__success __retval(64)
 91int bits_memalloc(void)
 92{
 93	u64 data[2];
 94	int nr = 0;
 95	int *bit;
 96
 97	__builtin_memset(&data, 0xf0, sizeof(data)); /* 4 * 16 */
 98	bpf_for_each(bits, bit, &data[0], ARRAY_SIZE(data))
 99		nr++;
100	return nr;
101}
102
103SEC("syscall")
104__description("bit index")
105__success __retval(8)
106int bit_index(void)
107{
108	u64 data = 0x100;
109	int bit_idx = 0;
110	int *bit;
111
112	bpf_for_each(bits, bit, &data, 1) {
113		if (*bit == 0)
114			continue;
115		bit_idx = *bit;
116	}
117	return bit_idx;
118}
119
120SEC("syscall")
121__description("bits too big")
122__success __retval(0)
123int bits_too_big(void)
124{
125	u64 data[4];
126	int nr = 0;
127	int *bit;
128
129	__builtin_memset(&data, 0xff, sizeof(data));
130	bpf_for_each(bits, bit, &data[0], 512) /* Be greater than 511 */
131		nr++;
132	return nr;
133}
134
135SEC("syscall")
136__description("fewer words")
137__success __retval(1)
138int fewer_words(void)
139{
140	u64 data[2] = {0x1, 0xff};
141	int nr = 0;
142	int *bit;
143
144	bpf_for_each(bits, bit, &data[0], 1)
145		nr++;
146	return nr;
147}
148
149SEC("syscall")
150__description("zero words")
151__success __retval(0)
152int zero_words(void)
153{
154	u64 data[2] = {0x1, 0xff};
155	int nr = 0;
156	int *bit;
157
158	bpf_for_each(bits, bit, &data[0], 0)
159		nr++;
160	return nr;
161}
162
163SEC("syscall")
164__description("huge words")
165__success __retval(0)
166int huge_words(void)
167{
168	u64 data[8] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
169	int nr = 0;
170	int *bit;
171
172	bpf_for_each(bits, bit, &data[0], 67108865)
173		nr++;
174	return nr;
175}
176
177SEC("syscall")
178__description("max words")
179__success __retval(4)
180int max_words(void)
181{
182	volatile int nr = 0;
183	int *bit;
184
185	bits_array[0] = (1ULL << 63) | 1U;
186	bits_array[510] = (1ULL << 33) | (1ULL << 32);
187
188	bpf_for_each(bits, bit, bits_array, 511) {
189		if (nr == 0 && *bit != 0)
190			break;
191		if (nr == 2 && *bit != 32672)
192			break;
193		nr++;
194	}
195	return nr;
196}
197
198SEC("syscall")
199__description("bad words")
200__success __retval(0)
201int bad_words(void)
202{
203	void *bad_addr = (void *)-4095;
204	struct bpf_iter_bits iter;
205	volatile int nr;
206	int *bit;
207	int err;
208
209	err = bpf_iter_bits_new(&iter, bad_addr, 1);
210	bpf_iter_bits_destroy(&iter);
211	if (err != -EFAULT)
212		return 1;
213
214	nr = 0;
215	bpf_for_each(bits, bit, bad_addr, 1)
216		nr++;
217	if (nr != 0)
218		return 2;
219
220	err = bpf_iter_bits_new(&iter, bad_addr, 4);
221	bpf_iter_bits_destroy(&iter);
222	if (err != -EFAULT)
223		return 3;
224
225	nr = 0;
226	bpf_for_each(bits, bit, bad_addr, 4)
227		nr++;
228	if (nr != 0)
229		return 4;
230
231	return 0;
232}