xref: /linux/tools/testing/selftests/bpf/prog_tests/arena_direct_value.c (revision 5a8cd539ac19f7a68e68e1d25ef9ca2ff55b8500)
17bfb93e3SWoojin Ji // SPDX-License-Identifier: GPL-2.0
27bfb93e3SWoojin Ji 
37bfb93e3SWoojin Ji #include <test_progs.h>
47bfb93e3SWoojin Ji #include <bpf/bpf.h>
57bfb93e3SWoojin Ji #include <errno.h>
67bfb93e3SWoojin Ji #include <sys/mman.h>
77bfb93e3SWoojin Ji #include <unistd.h>
87bfb93e3SWoojin Ji 
97bfb93e3SWoojin Ji #define ARENA_PAGES 32
107bfb93e3SWoojin Ji 
117bfb93e3SWoojin Ji static char log_buf[16384];
127bfb93e3SWoojin Ji 
test_arena_direct_value_one_past_end(void)137bfb93e3SWoojin Ji static void test_arena_direct_value_one_past_end(void)
147bfb93e3SWoojin Ji {
157bfb93e3SWoojin Ji 	char expected[128];
167bfb93e3SWoojin Ji 	__u32 arena_sz = ARENA_PAGES * getpagesize();
177bfb93e3SWoojin Ji 	struct bpf_insn insns[] = {
187bfb93e3SWoojin Ji 		BPF_LD_IMM64_RAW(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, 0),
197bfb93e3SWoojin Ji 		BPF_MOV64_IMM(BPF_REG_0, 0),
207bfb93e3SWoojin Ji 		BPF_EXIT_INSN(),
217bfb93e3SWoojin Ji 	};
227bfb93e3SWoojin Ji 	LIBBPF_OPTS(bpf_map_create_opts, map_opts);
237bfb93e3SWoojin Ji 	LIBBPF_OPTS(bpf_prog_load_opts, prog_opts);
247bfb93e3SWoojin Ji 	void *arena;
257bfb93e3SWoojin Ji 	int map_fd, prog_fd;
267bfb93e3SWoojin Ji 
277bfb93e3SWoojin Ji 	map_opts.map_flags = BPF_F_MMAPABLE;
287bfb93e3SWoojin Ji 	prog_opts.log_buf = log_buf;
297bfb93e3SWoojin Ji 	prog_opts.log_size = sizeof(log_buf);
307bfb93e3SWoojin Ji 	prog_opts.log_level = 1;
317bfb93e3SWoojin Ji 
327bfb93e3SWoojin Ji 	map_fd = bpf_map_create(BPF_MAP_TYPE_ARENA, "arena_direct_value",
337bfb93e3SWoojin Ji 				0, 0, ARENA_PAGES, &map_opts);
347bfb93e3SWoojin Ji 	if (map_fd < 0) {
357bfb93e3SWoojin Ji 		if (errno == EOPNOTSUPP) {
367bfb93e3SWoojin Ji 			test__skip();
377bfb93e3SWoojin Ji 			return;
387bfb93e3SWoojin Ji 		}
397bfb93e3SWoojin Ji 		ASSERT_GE(map_fd, 0, "bpf_map_create");
407bfb93e3SWoojin Ji 		return;
417bfb93e3SWoojin Ji 	}
427bfb93e3SWoojin Ji 
437bfb93e3SWoojin Ji 	arena = mmap(NULL, arena_sz, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
447bfb93e3SWoojin Ji 	if (!ASSERT_NEQ(arena, MAP_FAILED, "arena_mmap"))
457bfb93e3SWoojin Ji 		goto cleanup;
467bfb93e3SWoojin Ji 
477bfb93e3SWoojin Ji 	insns[0].imm = map_fd;
487bfb93e3SWoojin Ji 	insns[1].imm = arena_sz;
497bfb93e3SWoojin Ji 
507bfb93e3SWoojin Ji 	prog_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT,
517bfb93e3SWoojin Ji 				"arena_direct_value", "GPL", insns,
527bfb93e3SWoojin Ji 				ARRAY_SIZE(insns), &prog_opts);
537bfb93e3SWoojin Ji 	if (!ASSERT_LT(prog_fd, 0, "prog_load")) {
547bfb93e3SWoojin Ji 		close(prog_fd);
557bfb93e3SWoojin Ji 		goto cleanup;
567bfb93e3SWoojin Ji 	}
577bfb93e3SWoojin Ji 
587bfb93e3SWoojin Ji 	snprintf(expected, sizeof(expected),
597bfb93e3SWoojin Ji 		 "invalid access to map value pointer, value_size=0 off=%u",
607bfb93e3SWoojin Ji 		 arena_sz);
617bfb93e3SWoojin Ji 	ASSERT_HAS_SUBSTR(log_buf, expected, "verifier_log");
627bfb93e3SWoojin Ji 
637bfb93e3SWoojin Ji cleanup:
647bfb93e3SWoojin Ji 	if (arena != MAP_FAILED)
657bfb93e3SWoojin Ji 		munmap(arena, arena_sz);
667bfb93e3SWoojin Ji 	close(map_fd);
677bfb93e3SWoojin Ji }
687bfb93e3SWoojin Ji 
serial_test_arena_direct_value(void)69*a14f9ba0SJiayuan Chen void serial_test_arena_direct_value(void)
707bfb93e3SWoojin Ji {
717bfb93e3SWoojin Ji 	if (test__start_subtest("one_past_end"))
727bfb93e3SWoojin Ji 		test_arena_direct_value_one_past_end();
737bfb93e3SWoojin Ji }
74