xref: /linux/tools/testing/selftests/bpf/progs/access_map_in_map.c (revision 4b660dbd9ee2059850fd30e0df420ca7a38a1856)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2023. Huawei Technologies Co., Ltd */
3 #include <linux/bpf.h>
4 #include <time.h>
5 #include <bpf/bpf_helpers.h>
6 
7 #include "bpf_misc.h"
8 
9 struct inner_map_type {
10 	__uint(type, BPF_MAP_TYPE_ARRAY);
11 	__uint(key_size, 4);
12 	__uint(value_size, 4);
13 	__uint(max_entries, 1);
14 } inner_map SEC(".maps");
15 
16 struct {
17 	__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
18 	__type(key, int);
19 	__type(value, int);
20 	__uint(max_entries, 1);
21 	__array(values, struct inner_map_type);
22 } outer_array_map SEC(".maps") = {
23 	.values = {
24 		[0] = &inner_map,
25 	},
26 };
27 
28 struct {
29 	__uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
30 	__type(key, int);
31 	__type(value, int);
32 	__uint(max_entries, 1);
33 	__array(values, struct inner_map_type);
34 } outer_htab_map SEC(".maps") = {
35 	.values = {
36 		[0] = &inner_map,
37 	},
38 };
39 
40 char _license[] SEC("license") = "GPL";
41 
42 int tgid = 0;
43 
44 static int acc_map_in_map(void *outer_map)
45 {
46 	int i, key, value = 0xdeadbeef;
47 	void *inner_map;
48 
49 	if ((bpf_get_current_pid_tgid() >> 32) != tgid)
50 		return 0;
51 
52 	/* Find nonexistent inner map */
53 	key = 1;
54 	inner_map = bpf_map_lookup_elem(outer_map, &key);
55 	if (inner_map)
56 		return 0;
57 
58 	/* Find the old inner map */
59 	key = 0;
60 	inner_map = bpf_map_lookup_elem(outer_map, &key);
61 	if (!inner_map)
62 		return 0;
63 
64 	/* Wait for the old inner map to be replaced */
65 	for (i = 0; i < 2048; i++)
66 		bpf_map_update_elem(inner_map, &key, &value, 0);
67 
68 	return 0;
69 }
70 
71 SEC("?kprobe/" SYS_PREFIX "sys_getpgid")
72 int access_map_in_array(void *ctx)
73 {
74 	return acc_map_in_map(&outer_array_map);
75 }
76 
77 SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
78 int sleepable_access_map_in_array(void *ctx)
79 {
80 	return acc_map_in_map(&outer_array_map);
81 }
82 
83 SEC("?kprobe/" SYS_PREFIX "sys_getpgid")
84 int access_map_in_htab(void *ctx)
85 {
86 	return acc_map_in_map(&outer_htab_map);
87 }
88 
89 SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
90 int sleepable_access_map_in_htab(void *ctx)
91 {
92 	return acc_map_in_map(&outer_htab_map);
93 }
94