Skip to content

Commit 1fb5ba2

Browse files
jrfastabborkmann
authored andcommitted
bpf: Selftest to verify mixing bpf2bpf calls and tailcalls with insn patch
This adds some extra noise to the tailcall_bpf2bpf4 tests that will cause verify to patch insns. This then moves around subprog start/end insn index and poke descriptor insn index to ensure that verify and JIT will continue to track these correctly. If done correctly verifier should pass this program same as before and JIT should emit tail call logic. Signed-off-by: John Fastabend <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent f263a81 commit 1fb5ba2

File tree

2 files changed

+44
-10
lines changed

2 files changed

+44
-10
lines changed

tools/testing/selftests/bpf/prog_tests/tailcalls.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,8 @@ static void test_tailcall_bpf2bpf_3(void)
715715
bpf_object__close(obj);
716716
}
717717

718+
#include "tailcall_bpf2bpf4.skel.h"
719+
718720
/* test_tailcall_bpf2bpf_4 checks that tailcall counter is correctly preserved
719721
* across tailcalls combined with bpf2bpf calls. for making sure that tailcall
720722
* counter behaves correctly, bpf program will go through following flow:
@@ -727,10 +729,15 @@ static void test_tailcall_bpf2bpf_3(void)
727729
* the loop begins. At the end of the test make sure that the global counter is
728730
* equal to 31, because tailcall counter includes the first two tailcalls
729731
* whereas global counter is incremented only on loop presented on flow above.
732+
*
733+
* The noise parameter is used to insert bpf_map_update calls into the logic
734+
* to force verifier to patch instructions. This allows us to ensure jump
735+
* logic remains correct with instruction movement.
730736
*/
731-
static void test_tailcall_bpf2bpf_4(void)
737+
static void test_tailcall_bpf2bpf_4(bool noise)
732738
{
733-
int err, map_fd, prog_fd, main_fd, data_fd, i, val;
739+
int err, map_fd, prog_fd, main_fd, data_fd, i;
740+
struct tailcall_bpf2bpf4__bss val;
734741
struct bpf_map *prog_array, *data_map;
735742
struct bpf_program *prog;
736743
struct bpf_object *obj;
@@ -774,11 +781,6 @@ static void test_tailcall_bpf2bpf_4(void)
774781
goto out;
775782
}
776783

777-
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0,
778-
&duration, &retval, NULL);
779-
CHECK(err || retval != sizeof(pkt_v4) * 3, "tailcall", "err %d errno %d retval %d\n",
780-
err, errno, retval);
781-
782784
data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
783785
if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
784786
return;
@@ -787,10 +789,22 @@ static void test_tailcall_bpf2bpf_4(void)
787789
if (CHECK_FAIL(map_fd < 0))
788790
return;
789791

792+
i = 0;
793+
val.noise = noise;
794+
val.count = 0;
795+
err = bpf_map_update_elem(data_fd, &i, &val, BPF_ANY);
796+
if (CHECK_FAIL(err))
797+
goto out;
798+
799+
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0,
800+
&duration, &retval, NULL);
801+
CHECK(err || retval != sizeof(pkt_v4) * 3, "tailcall", "err %d errno %d retval %d\n",
802+
err, errno, retval);
803+
790804
i = 0;
791805
err = bpf_map_lookup_elem(data_fd, &i, &val);
792-
CHECK(err || val != 31, "tailcall count", "err %d errno %d count %d\n",
793-
err, errno, val);
806+
CHECK(err || val.count != 31, "tailcall count", "err %d errno %d count %d\n",
807+
err, errno, val.count);
794808

795809
out:
796810
bpf_object__close(obj);
@@ -815,5 +829,7 @@ void test_tailcalls(void)
815829
if (test__start_subtest("tailcall_bpf2bpf_3"))
816830
test_tailcall_bpf2bpf_3();
817831
if (test__start_subtest("tailcall_bpf2bpf_4"))
818-
test_tailcall_bpf2bpf_4();
832+
test_tailcall_bpf2bpf_4(false);
833+
if (test__start_subtest("tailcall_bpf2bpf_5"))
834+
test_tailcall_bpf2bpf_4(true);
819835
}

tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
#include <linux/bpf.h>
33
#include <bpf/bpf_helpers.h>
44

5+
struct {
6+
__uint(type, BPF_MAP_TYPE_ARRAY);
7+
__uint(max_entries, 1);
8+
__uint(key_size, sizeof(__u32));
9+
__uint(value_size, sizeof(__u32));
10+
} nop_table SEC(".maps");
11+
512
struct {
613
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
714
__uint(max_entries, 3);
@@ -10,10 +17,21 @@ struct {
1017
} jmp_table SEC(".maps");
1118

1219
int count = 0;
20+
int noise = 0;
21+
22+
__always_inline int subprog_noise(void)
23+
{
24+
__u32 key = 0;
25+
26+
bpf_map_lookup_elem(&nop_table, &key);
27+
return 0;
28+
}
1329

1430
__noinline
1531
int subprog_tail_2(struct __sk_buff *skb)
1632
{
33+
if (noise)
34+
subprog_noise();
1735
bpf_tail_call_static(skb, &jmp_table, 2);
1836
return skb->len * 3;
1937
}

0 commit comments

Comments
 (0)