xref: /linux/tools/testing/selftests/bpf/progs/test_global_percpu_data.c (revision 5a8cd539ac19f7a68e68e1d25ef9ca2ff55b8500)
14c9241bdSLeon Hwang // SPDX-License-Identifier: GPL-2.0
24c9241bdSLeon Hwang #include <vmlinux.h>
34c9241bdSLeon Hwang #include <bpf/bpf_helpers.h>
44c9241bdSLeon Hwang #include "bpf_misc.h"
54c9241bdSLeon Hwang 
64c9241bdSLeon Hwang /* Used for testing map name. */
74c9241bdSLeon Hwang int loong SEC(".percpu.looooooooong");
84c9241bdSLeon Hwang int data3 SEC(".data.percpu");
94c9241bdSLeon Hwang int data2 SEC(".percpu.data");
104c9241bdSLeon Hwang 
114c9241bdSLeon Hwang int run;
124c9241bdSLeon Hwang /* cpu_id as array to verify map value resizing. */
134c9241bdSLeon Hwang int cpu_id[1] SEC(".percpu");
144c9241bdSLeon Hwang int data SEC(".percpu") = -1;
154c9241bdSLeon Hwang int nums[7] SEC(".percpu");
164c9241bdSLeon Hwang bool set SEC(".percpu") = false;
174c9241bdSLeon Hwang struct {
184c9241bdSLeon Hwang 	char set;
194c9241bdSLeon Hwang 	int i;
204c9241bdSLeon Hwang 	int nums[7];
214c9241bdSLeon Hwang } struct_data SEC(".percpu") = {
224c9241bdSLeon Hwang 	.set = 0,
234c9241bdSLeon Hwang 	.i = -1,
244c9241bdSLeon Hwang };
254c9241bdSLeon Hwang 
264c9241bdSLeon Hwang SEC("raw_tp/task_rename")
274c9241bdSLeon Hwang __auxiliary
update_percpu_data(void * ctx)284c9241bdSLeon Hwang int update_percpu_data(void *ctx)
294c9241bdSLeon Hwang {
304c9241bdSLeon Hwang 	struct_data.nums[6] = 0xc0de;
314c9241bdSLeon Hwang 	struct_data.set = 1;
324c9241bdSLeon Hwang 	struct_data.i = 1;
334c9241bdSLeon Hwang 	nums[6] = 0xc0de;
344c9241bdSLeon Hwang 	data = 1;
354c9241bdSLeon Hwang 	run++;
364c9241bdSLeon Hwang 	set = true;
374c9241bdSLeon Hwang 	cpu_id[0] = bpf_get_smp_processor_id();
384c9241bdSLeon Hwang 	return 0;
394c9241bdSLeon Hwang }
404c9241bdSLeon Hwang 
411ed2294bSLeon Hwang static const char fmt[] SEC(".percpu.fmt") = "data %d\n";
421ed2294bSLeon Hwang 
431ed2294bSLeon Hwang SEC("?kprobe")
441ed2294bSLeon Hwang __failure __msg("R{{[0-9]+}} points to percpu_array map which cannot be used as const string")
verifier_strncmp(void * ctx)451ed2294bSLeon Hwang int verifier_strncmp(void *ctx)
461ed2294bSLeon Hwang {
471ed2294bSLeon Hwang 	return bpf_strncmp("test", 5, fmt);
481ed2294bSLeon Hwang }
491ed2294bSLeon Hwang 
501ed2294bSLeon Hwang SEC("?kprobe")
511ed2294bSLeon Hwang __failure __msg("R{{[0-9]+}} points to percpu_array map which cannot be used as const string")
verifier_snprintf(void * ctx)521ed2294bSLeon Hwang int verifier_snprintf(void *ctx)
531ed2294bSLeon Hwang {
541ed2294bSLeon Hwang 	u64 args[] = { data };
551ed2294bSLeon Hwang 	char buf[128];
561ed2294bSLeon Hwang 	int len;
571ed2294bSLeon Hwang 
581ed2294bSLeon Hwang 	len = bpf_snprintf(buf, sizeof(buf), fmt, args, sizeof(args));
591ed2294bSLeon Hwang 	if (len > 0)
601ed2294bSLeon Hwang 		bpf_printk("snprintf: %s\n", buf);
611ed2294bSLeon Hwang 	return 0;
621ed2294bSLeon Hwang }
631ed2294bSLeon Hwang 
6415945d02SLeon Hwang volatile const __u32 num_cpus = 0;
65*90bd0329SLeon Hwang volatile const int num_off;
6615945d02SLeon Hwang volatile const int elem_sz;
67*90bd0329SLeon Hwang __u32 sum = 0;
6815945d02SLeon Hwang bool run_iter = false;
6915945d02SLeon Hwang 
7015945d02SLeon Hwang SEC("iter/bpf_map_elem")
7115945d02SLeon Hwang __auxiliary
dump_percpu_data(struct bpf_iter__bpf_map_elem * ctx)7215945d02SLeon Hwang int dump_percpu_data(struct bpf_iter__bpf_map_elem *ctx)
7315945d02SLeon Hwang {
7415945d02SLeon Hwang 	void *pptr = ctx->value;
7515945d02SLeon Hwang 	int i;
7615945d02SLeon Hwang 
7715945d02SLeon Hwang 	if (!pptr)
7815945d02SLeon Hwang 		return 0;
7915945d02SLeon Hwang 
8015945d02SLeon Hwang 	run_iter = true;
8115945d02SLeon Hwang 
8215945d02SLeon Hwang 	for (i = 0; i < num_cpus; i++) {
83*90bd0329SLeon Hwang 		sum += *(int *) (pptr + num_off);
8415945d02SLeon Hwang 		pptr += elem_sz;
8515945d02SLeon Hwang 	}
8615945d02SLeon Hwang 	return 0;
8715945d02SLeon Hwang }
8815945d02SLeon Hwang 
894c9241bdSLeon Hwang char _license[] SEC("license") = "GPL";
90