Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2#include <vmlinux.h>
  3#include <bpf/bpf_tracing.h>
  4#include <bpf/bpf_helpers.h>
  5#include "bpf_experimental.h"
  6
  7struct foo {
  8	struct bpf_spin_lock lock;
  9	int data;
 10};
 11
 12struct array_map {
 13	__uint(type, BPF_MAP_TYPE_ARRAY);
 14	__type(key, int);
 15	__type(value, struct foo);
 16	__uint(max_entries, 1);
 17} array_map SEC(".maps");
 18
 19struct {
 20	__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
 21	__uint(max_entries, 1);
 22	__type(key, int);
 23	__type(value, int);
 24	__array(values, struct array_map);
 25} map_of_maps SEC(".maps") = {
 26	.values = {
 27		[0] = &array_map,
 28	},
 29};
 30
 31static struct bpf_spin_lock lockA SEC(".data.A");
 32static struct bpf_spin_lock lockB SEC(".data.B");
 33
 34SEC("?tc")
 35int lock_id_kptr_preserve(void *ctx)
 36{
 37	struct foo *f;
 38
 39	f = bpf_obj_new(typeof(*f));
 40	if (!f)
 41		return 0;
 42	bpf_this_cpu_ptr(f);
 43	return 0;
 44}
 45
 46SEC("?tc")
 47int lock_id_global_zero(void *ctx)
 48{
 49	bpf_this_cpu_ptr(&lockA);
 50	return 0;
 51}
 52
 53SEC("?tc")
 54int lock_id_mapval_preserve(void *ctx)
 55{
 56	struct foo *f;
 57	int key = 0;
 58
 59	f = bpf_map_lookup_elem(&array_map, &key);
 60	if (!f)
 61		return 0;
 62	bpf_this_cpu_ptr(f);
 63	return 0;
 64}
 65
 66SEC("?tc")
 67int lock_id_innermapval_preserve(void *ctx)
 68{
 69	struct foo *f;
 70	int key = 0;
 71	void *map;
 72
 73	map = bpf_map_lookup_elem(&map_of_maps, &key);
 74	if (!map)
 75		return 0;
 76	f = bpf_map_lookup_elem(map, &key);
 77	if (!f)
 78		return 0;
 79	bpf_this_cpu_ptr(f);
 80	return 0;
 81}
 82
 83#define CHECK(test, A, B)                                      \
 84	SEC("?tc")                                             \
 85	int lock_id_mismatch_##test(void *ctx)                 \
 86	{                                                      \
 87		struct foo *f1, *f2, *v, *iv;                  \
 88		int key = 0;                                   \
 89		void *map;                                     \
 90                                                               \
 91		map = bpf_map_lookup_elem(&map_of_maps, &key); \
 92		if (!map)                                      \
 93			return 0;                              \
 94		iv = bpf_map_lookup_elem(map, &key);           \
 95		if (!iv)                                       \
 96			return 0;                              \
 97		v = bpf_map_lookup_elem(&array_map, &key);     \
 98		if (!v)                                        \
 99			return 0;                              \
100		f1 = bpf_obj_new(typeof(*f1));                 \
101		if (!f1)                                       \
102			return 0;                              \
103		f2 = bpf_obj_new(typeof(*f2));                 \
104		if (!f2) {                                     \
105			bpf_obj_drop(f1);                      \
106			return 0;                              \
107		}                                              \
108		bpf_spin_lock(A);                              \
109		bpf_spin_unlock(B);                            \
110		return 0;                                      \
111	}
112
113CHECK(kptr_kptr, &f1->lock, &f2->lock);
114CHECK(kptr_global, &f1->lock, &lockA);
115CHECK(kptr_mapval, &f1->lock, &v->lock);
116CHECK(kptr_innermapval, &f1->lock, &iv->lock);
117
118CHECK(global_global, &lockA, &lockB);
119CHECK(global_kptr, &lockA, &f1->lock);
120CHECK(global_mapval, &lockA, &v->lock);
121CHECK(global_innermapval, &lockA, &iv->lock);
122
123SEC("?tc")
124int lock_id_mismatch_mapval_mapval(void *ctx)
125{
126	struct foo *f1, *f2;
127	int key = 0;
128
129	f1 = bpf_map_lookup_elem(&array_map, &key);
130	if (!f1)
131		return 0;
132	f2 = bpf_map_lookup_elem(&array_map, &key);
133	if (!f2)
134		return 0;
135
136	bpf_spin_lock(&f1->lock);
137	f1->data = 42;
138	bpf_spin_unlock(&f2->lock);
139
140	return 0;
141}
142
143CHECK(mapval_kptr, &v->lock, &f1->lock);
144CHECK(mapval_global, &v->lock, &lockB);
145CHECK(mapval_innermapval, &v->lock, &iv->lock);
146
147SEC("?tc")
148int lock_id_mismatch_innermapval_innermapval1(void *ctx)
149{
150	struct foo *f1, *f2;
151	int key = 0;
152	void *map;
153
154	map = bpf_map_lookup_elem(&map_of_maps, &key);
155	if (!map)
156		return 0;
157	f1 = bpf_map_lookup_elem(map, &key);
158	if (!f1)
159		return 0;
160	f2 = bpf_map_lookup_elem(map, &key);
161	if (!f2)
162		return 0;
163
164	bpf_spin_lock(&f1->lock);
165	f1->data = 42;
166	bpf_spin_unlock(&f2->lock);
167
168	return 0;
169}
170
171SEC("?tc")
172int lock_id_mismatch_innermapval_innermapval2(void *ctx)
173{
174	struct foo *f1, *f2;
175	int key = 0;
176	void *map;
177
178	map = bpf_map_lookup_elem(&map_of_maps, &key);
179	if (!map)
180		return 0;
181	f1 = bpf_map_lookup_elem(map, &key);
182	if (!f1)
183		return 0;
184	map = bpf_map_lookup_elem(&map_of_maps, &key);
185	if (!map)
186		return 0;
187	f2 = bpf_map_lookup_elem(map, &key);
188	if (!f2)
189		return 0;
190
191	bpf_spin_lock(&f1->lock);
192	f1->data = 42;
193	bpf_spin_unlock(&f2->lock);
194
195	return 0;
196}
197
198CHECK(innermapval_kptr, &iv->lock, &f1->lock);
199CHECK(innermapval_global, &iv->lock, &lockA);
200CHECK(innermapval_mapval, &iv->lock, &v->lock);
201
202#undef CHECK
203
204__noinline
205int global_subprog(struct __sk_buff *ctx)
206{
207	volatile int ret = 0;
208
209	if (ctx->protocol)
210		ret += ctx->protocol;
211	return ret + ctx->mark;
212}
213
214__noinline
215static int static_subprog_call_global(struct __sk_buff *ctx)
216{
217	volatile int ret = 0;
218
219	if (ctx->protocol)
220		return ret;
221	return ret + ctx->len + global_subprog(ctx);
222}
223
224SEC("?tc")
225int lock_global_subprog_call1(struct __sk_buff *ctx)
226{
227	int ret = 0;
228
229	bpf_spin_lock(&lockA);
230	if (ctx->mark == 42)
231		ret = global_subprog(ctx);
232	bpf_spin_unlock(&lockA);
233	return ret;
234}
235
236SEC("?tc")
237int lock_global_subprog_call2(struct __sk_buff *ctx)
238{
239	int ret = 0;
240
241	bpf_spin_lock(&lockA);
242	if (ctx->mark == 42)
243		ret = static_subprog_call_global(ctx);
244	bpf_spin_unlock(&lockA);
245	return ret;
246}
247
248char _license[] SEC("license") = "GPL";
v6.8
  1// SPDX-License-Identifier: GPL-2.0
  2#include <vmlinux.h>
  3#include <bpf/bpf_tracing.h>
  4#include <bpf/bpf_helpers.h>
  5#include "bpf_experimental.h"
  6
  7struct foo {
  8	struct bpf_spin_lock lock;
  9	int data;
 10};
 11
 12struct array_map {
 13	__uint(type, BPF_MAP_TYPE_ARRAY);
 14	__type(key, int);
 15	__type(value, struct foo);
 16	__uint(max_entries, 1);
 17} array_map SEC(".maps");
 18
 19struct {
 20	__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
 21	__uint(max_entries, 1);
 22	__type(key, int);
 23	__type(value, int);
 24	__array(values, struct array_map);
 25} map_of_maps SEC(".maps") = {
 26	.values = {
 27		[0] = &array_map,
 28	},
 29};
 30
 31SEC(".data.A") struct bpf_spin_lock lockA;
 32SEC(".data.B") struct bpf_spin_lock lockB;
 33
 34SEC("?tc")
 35int lock_id_kptr_preserve(void *ctx)
 36{
 37	struct foo *f;
 38
 39	f = bpf_obj_new(typeof(*f));
 40	if (!f)
 41		return 0;
 42	bpf_this_cpu_ptr(f);
 43	return 0;
 44}
 45
 46SEC("?tc")
 47int lock_id_global_zero(void *ctx)
 48{
 49	bpf_this_cpu_ptr(&lockA);
 50	return 0;
 51}
 52
 53SEC("?tc")
 54int lock_id_mapval_preserve(void *ctx)
 55{
 56	struct foo *f;
 57	int key = 0;
 58
 59	f = bpf_map_lookup_elem(&array_map, &key);
 60	if (!f)
 61		return 0;
 62	bpf_this_cpu_ptr(f);
 63	return 0;
 64}
 65
 66SEC("?tc")
 67int lock_id_innermapval_preserve(void *ctx)
 68{
 69	struct foo *f;
 70	int key = 0;
 71	void *map;
 72
 73	map = bpf_map_lookup_elem(&map_of_maps, &key);
 74	if (!map)
 75		return 0;
 76	f = bpf_map_lookup_elem(map, &key);
 77	if (!f)
 78		return 0;
 79	bpf_this_cpu_ptr(f);
 80	return 0;
 81}
 82
 83#define CHECK(test, A, B)                                      \
 84	SEC("?tc")                                             \
 85	int lock_id_mismatch_##test(void *ctx)                 \
 86	{                                                      \
 87		struct foo *f1, *f2, *v, *iv;                  \
 88		int key = 0;                                   \
 89		void *map;                                     \
 90                                                               \
 91		map = bpf_map_lookup_elem(&map_of_maps, &key); \
 92		if (!map)                                      \
 93			return 0;                              \
 94		iv = bpf_map_lookup_elem(map, &key);           \
 95		if (!iv)                                       \
 96			return 0;                              \
 97		v = bpf_map_lookup_elem(&array_map, &key);     \
 98		if (!v)                                        \
 99			return 0;                              \
100		f1 = bpf_obj_new(typeof(*f1));                 \
101		if (!f1)                                       \
102			return 0;                              \
103		f2 = bpf_obj_new(typeof(*f2));                 \
104		if (!f2) {                                     \
105			bpf_obj_drop(f1);                      \
106			return 0;                              \
107		}                                              \
108		bpf_spin_lock(A);                              \
109		bpf_spin_unlock(B);                            \
110		return 0;                                      \
111	}
112
113CHECK(kptr_kptr, &f1->lock, &f2->lock);
114CHECK(kptr_global, &f1->lock, &lockA);
115CHECK(kptr_mapval, &f1->lock, &v->lock);
116CHECK(kptr_innermapval, &f1->lock, &iv->lock);
117
118CHECK(global_global, &lockA, &lockB);
119CHECK(global_kptr, &lockA, &f1->lock);
120CHECK(global_mapval, &lockA, &v->lock);
121CHECK(global_innermapval, &lockA, &iv->lock);
122
123SEC("?tc")
124int lock_id_mismatch_mapval_mapval(void *ctx)
125{
126	struct foo *f1, *f2;
127	int key = 0;
128
129	f1 = bpf_map_lookup_elem(&array_map, &key);
130	if (!f1)
131		return 0;
132	f2 = bpf_map_lookup_elem(&array_map, &key);
133	if (!f2)
134		return 0;
135
136	bpf_spin_lock(&f1->lock);
137	f1->data = 42;
138	bpf_spin_unlock(&f2->lock);
139
140	return 0;
141}
142
143CHECK(mapval_kptr, &v->lock, &f1->lock);
144CHECK(mapval_global, &v->lock, &lockB);
145CHECK(mapval_innermapval, &v->lock, &iv->lock);
146
147SEC("?tc")
148int lock_id_mismatch_innermapval_innermapval1(void *ctx)
149{
150	struct foo *f1, *f2;
151	int key = 0;
152	void *map;
153
154	map = bpf_map_lookup_elem(&map_of_maps, &key);
155	if (!map)
156		return 0;
157	f1 = bpf_map_lookup_elem(map, &key);
158	if (!f1)
159		return 0;
160	f2 = bpf_map_lookup_elem(map, &key);
161	if (!f2)
162		return 0;
163
164	bpf_spin_lock(&f1->lock);
165	f1->data = 42;
166	bpf_spin_unlock(&f2->lock);
167
168	return 0;
169}
170
171SEC("?tc")
172int lock_id_mismatch_innermapval_innermapval2(void *ctx)
173{
174	struct foo *f1, *f2;
175	int key = 0;
176	void *map;
177
178	map = bpf_map_lookup_elem(&map_of_maps, &key);
179	if (!map)
180		return 0;
181	f1 = bpf_map_lookup_elem(map, &key);
182	if (!f1)
183		return 0;
184	map = bpf_map_lookup_elem(&map_of_maps, &key);
185	if (!map)
186		return 0;
187	f2 = bpf_map_lookup_elem(map, &key);
188	if (!f2)
189		return 0;
190
191	bpf_spin_lock(&f1->lock);
192	f1->data = 42;
193	bpf_spin_unlock(&f2->lock);
194
195	return 0;
196}
197
198CHECK(innermapval_kptr, &iv->lock, &f1->lock);
199CHECK(innermapval_global, &iv->lock, &lockA);
200CHECK(innermapval_mapval, &iv->lock, &v->lock);
201
202#undef CHECK
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
204char _license[] SEC("license") = "GPL";