xref: /openbmc/linux/samples/bpf/syscall_tp_user.c (revision 25763b3c)
125763b3cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21da236b6SYonghong Song /* Copyright (c) 2017 Facebook
31da236b6SYonghong Song  */
41da236b6SYonghong Song #include <stdio.h>
51da236b6SYonghong Song #include <unistd.h>
61da236b6SYonghong Song #include <fcntl.h>
71da236b6SYonghong Song #include <stdlib.h>
81da236b6SYonghong Song #include <signal.h>
91da236b6SYonghong Song #include <linux/bpf.h>
101da236b6SYonghong Song #include <string.h>
111da236b6SYonghong Song #include <linux/perf_event.h>
121da236b6SYonghong Song #include <errno.h>
131da236b6SYonghong Song #include <assert.h>
141da236b6SYonghong Song #include <stdbool.h>
151da236b6SYonghong Song #include <sys/resource.h>
162bf3e2efSJakub Kicinski #include <bpf/bpf.h>
171da236b6SYonghong Song #include "bpf_load.h"
181da236b6SYonghong Song 
191da236b6SYonghong Song /* This program verifies bpf attachment to tracepoint sys_enter_* and sys_exit_*.
201da236b6SYonghong Song  * This requires kernel CONFIG_FTRACE_SYSCALLS to be set.
211da236b6SYonghong Song  */
221da236b6SYonghong Song 
23a678be5cSYonghong Song static void usage(const char *cmd)
24a678be5cSYonghong Song {
25a678be5cSYonghong Song 	printf("USAGE: %s [-i num_progs] [-h]\n", cmd);
26a678be5cSYonghong Song 	printf("       -i num_progs      # number of progs of the test\n");
27a678be5cSYonghong Song 	printf("       -h                # help\n");
28a678be5cSYonghong Song }
29a678be5cSYonghong Song 
301da236b6SYonghong Song static void verify_map(int map_id)
311da236b6SYonghong Song {
321da236b6SYonghong Song 	__u32 key = 0;
331da236b6SYonghong Song 	__u32 val;
341da236b6SYonghong Song 
351da236b6SYonghong Song 	if (bpf_map_lookup_elem(map_id, &key, &val) != 0) {
361da236b6SYonghong Song 		fprintf(stderr, "map_lookup failed: %s\n", strerror(errno));
371da236b6SYonghong Song 		return;
381da236b6SYonghong Song 	}
39a678be5cSYonghong Song 	if (val == 0) {
401da236b6SYonghong Song 		fprintf(stderr, "failed: map #%d returns value 0\n", map_id);
41a678be5cSYonghong Song 		return;
42a678be5cSYonghong Song 	}
43a678be5cSYonghong Song 	val = 0;
44a678be5cSYonghong Song 	if (bpf_map_update_elem(map_id, &key, &val, BPF_ANY) != 0) {
45a678be5cSYonghong Song 		fprintf(stderr, "map_update failed: %s\n", strerror(errno));
46a678be5cSYonghong Song 		return;
47a678be5cSYonghong Song 	}
481da236b6SYonghong Song }
491da236b6SYonghong Song 
50a678be5cSYonghong Song static int test(char *filename, int num_progs)
511da236b6SYonghong Song {
52a678be5cSYonghong Song 	int i, fd, map0_fds[num_progs], map1_fds[num_progs];
531da236b6SYonghong Song 
54a678be5cSYonghong Song 	for (i = 0; i < num_progs; i++) {
551da236b6SYonghong Song 		if (load_bpf_file(filename)) {
561da236b6SYonghong Song 			fprintf(stderr, "%s", bpf_log_buf);
571da236b6SYonghong Song 			return 1;
581da236b6SYonghong Song 		}
59a678be5cSYonghong Song 		printf("prog #%d: map ids %d %d\n", i, map_fd[0], map_fd[1]);
60a678be5cSYonghong Song 		map0_fds[i] = map_fd[0];
61a678be5cSYonghong Song 		map1_fds[i] = map_fd[1];
62a678be5cSYonghong Song 	}
631da236b6SYonghong Song 
641da236b6SYonghong Song 	/* current load_bpf_file has perf_event_open default pid = -1
651da236b6SYonghong Song 	 * and cpu = 0, which permits attached bpf execution on
661da236b6SYonghong Song 	 * all cpus for all pid's. bpf program execution ignores
671da236b6SYonghong Song 	 * cpu affinity.
681da236b6SYonghong Song 	 */
691da236b6SYonghong Song 	/* trigger some "open" operations */
701da236b6SYonghong Song 	fd = open(filename, O_RDONLY);
711da236b6SYonghong Song 	if (fd < 0) {
721da236b6SYonghong Song 		fprintf(stderr, "open failed: %s\n", strerror(errno));
731da236b6SYonghong Song 		return 1;
741da236b6SYonghong Song 	}
751da236b6SYonghong Song 	close(fd);
761da236b6SYonghong Song 
771da236b6SYonghong Song 	/* verify the map */
78a678be5cSYonghong Song 	for (i = 0; i < num_progs; i++) {
79a678be5cSYonghong Song 		verify_map(map0_fds[i]);
80a678be5cSYonghong Song 		verify_map(map1_fds[i]);
81a678be5cSYonghong Song 	}
821da236b6SYonghong Song 
831da236b6SYonghong Song 	return 0;
841da236b6SYonghong Song }
85a678be5cSYonghong Song 
86a678be5cSYonghong Song int main(int argc, char **argv)
87a678be5cSYonghong Song {
88a678be5cSYonghong Song 	struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
89a678be5cSYonghong Song 	int opt, num_progs = 1;
90a678be5cSYonghong Song 	char filename[256];
91a678be5cSYonghong Song 
92a678be5cSYonghong Song 	while ((opt = getopt(argc, argv, "i:h")) != -1) {
93a678be5cSYonghong Song 		switch (opt) {
94a678be5cSYonghong Song 		case 'i':
95a678be5cSYonghong Song 			num_progs = atoi(optarg);
96a678be5cSYonghong Song 			break;
97a678be5cSYonghong Song 		case 'h':
98a678be5cSYonghong Song 		default:
99a678be5cSYonghong Song 			usage(argv[0]);
100a678be5cSYonghong Song 			return 0;
101a678be5cSYonghong Song 		}
102a678be5cSYonghong Song 	}
103a678be5cSYonghong Song 
104a678be5cSYonghong Song 	setrlimit(RLIMIT_MEMLOCK, &r);
105a678be5cSYonghong Song 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
106a678be5cSYonghong Song 
107a678be5cSYonghong Song 	return test(filename, num_progs);
108a678be5cSYonghong Song }
109