brintos

brintos / linux-shallow public Read only

0
0
Text · 5.3 KiB · 43f40c4 Raw
249 lines · c
1// SPDX-License-Identifier: GPL-2.02#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 CHECK203 204__noinline205int 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__noinline215static 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";249