public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
From: Anton Protopopov <a.s.protopopov@gmail.com>
To: Eduard Zingerman <eddyz87@gmail.com>
Cc: bpf@vger.kernel.org, Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Anton Protopopov <aspsk@isovalent.com>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Quentin Monnet <qmo@kernel.org>,
	Yonghong Song <yonghong.song@linux.dev>
Subject: Re: [PATCH v5 bpf-next 05/15] selftests/bpf: add selftests for new insn_array map
Date: Fri, 3 Oct 2025 07:46:38 +0000	[thread overview]
Message-ID: <aN9/XoodAYHN5Lm7@mail.gmail.com> (raw)
In-Reply-To: <b7ed4bb22cd73006f761888305ed7ed2f70a5071.camel@gmail.com>

On 25/10/02 06:16PM, Eduard Zingerman wrote:
> On Tue, 2025-09-30 at 12:51 +0000, Anton Protopopov wrote:
> 
> Overall lgtm, some code duplication worth removing, I think.
> 
> [...]
> 
> > +/*
> > + * Try to load a program with a map which points to outside of the program
> > + */
> > +static void check_out_of_bounds_index(void)
> > +{
> > +	struct bpf_insn insns[] = {
> > +		BPF_MOV64_IMM(BPF_REG_0, 4),
> > +		BPF_MOV64_IMM(BPF_REG_0, 3),
> > +		BPF_MOV64_IMM(BPF_REG_0, 2),
> > +		BPF_MOV64_IMM(BPF_REG_0, 1),
> > +		BPF_MOV64_IMM(BPF_REG_0, 0),
> > +		BPF_EXIT_INSN(),
> > +	};
> > +	int prog_fd, map_fd;
> > +	struct bpf_insn_array_value val = {};
> > +	int key;
> > +
> > +	map_fd = map_create(BPF_MAP_TYPE_INSN_ARRAY, 1);
> > +	if (!ASSERT_GE(map_fd, 0, "map_create"))
> > +		return;
> > +
> > +	key = 0;
> > +	val.xlated_off = ARRAY_SIZE(insns); /* too big */
> > +	if (!ASSERT_EQ(bpf_map_update_elem(map_fd, &key, &val, 0), 0, "bpf_map_update_elem"))
> > +		goto cleanup;
> > +
> > +	if (!ASSERT_EQ(bpf_map_freeze(map_fd), 0, "bpf_map_freeze"))
> > +		goto cleanup;
> > +
> > +	errno = 0;
> 
> Nit: errno is not used in the check below, hence there is no need to reset it.
>      (here and in other tests below)

Ok, will do.

> > +	prog_fd = prog_load(insns, ARRAY_SIZE(insns), &map_fd, 1);
> > +	if (!ASSERT_EQ(prog_fd, -EINVAL, "program should have been rejected (prog_fd != -EINVAL)")) {
> > +		close(prog_fd);
> > +		goto cleanup;
> > +	}
> > +
> > +cleanup:
> > +	close(map_fd);
> > +}
> 
> [...]
> 
> > +/*
> > + * Load a program with two patches (get jiffies, for simplicity). Add an
> > + * insn_array map pointing to every instruction. Check how it was changed
> > + * after the program load.
> > + */
> > +static void check_simple(void)
> > +{
> > +	struct bpf_insn insns[] = {
> > +		BPF_MOV64_IMM(BPF_REG_0, 2),
> > +		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
> > +		BPF_MOV64_IMM(BPF_REG_0, 1),
> > +		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
> > +		BPF_MOV64_IMM(BPF_REG_0, 0),
> > +		BPF_EXIT_INSN(),
> > +	};
> > +	int prog_fd = -1, map_fd;
> > +	__u32 map_in[] = {0, 1, 2, 3, 4, 5};
> > +	__u32 map_out[] = {0, 1, 4, 5, 8, 9};
> > +	struct bpf_insn_array_value val = {};
> > +	int i;
> > +
> > +	map_fd = map_create(BPF_MAP_TYPE_INSN_ARRAY, ARRAY_SIZE(insns));
> > +	if (!ASSERT_GE(map_fd, 0, "map_create"))
> > +		return;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(insns); i++) {
> > +		val.xlated_off = map_in[i];
> > +		if (!ASSERT_EQ(bpf_map_update_elem(map_fd, &i, &val, 0), 0,
> > +			       "bpf_map_update_elem"))
> > +			goto cleanup;
> > +	}
> > +
> > +	if (!ASSERT_EQ(bpf_map_freeze(map_fd), 0, "bpf_map_freeze"))
> > +		goto cleanup;
> > +
> > +	prog_fd = prog_load(insns, ARRAY_SIZE(insns), &map_fd, 1);
> > +	if (!ASSERT_GE(prog_fd, 0, "bpf(BPF_PROG_LOAD)"))
> > +		goto cleanup;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(insns); i++) {
> > +		if (!ASSERT_EQ(bpf_map_lookup_elem(map_fd, &i, &val), 0, "bpf_map_lookup_elem"))
> > +			goto cleanup;
> > +
> > +		ASSERT_EQ(val.xlated_off, map_out[i], "val should be equal map_out[i]");
> 
> Nit: maybe print `i`, `xlated_off` and `map_out[i]` here?

+1

> If this test fails, debugging it with -vvv would be inconvenient,
> as there is no way to see xlated program. Maybe extend load_prog()
> to check debug level and add capability to print xlated?
> See __xlated annotation implementation in selftests.

Ok, nice, will do.

Just in case, typically, when I write selftests I add smth like

    if (getenv("HANG") && *(getenv("HANG")))
        for (;;)
            pause();

before destroying skeleton, so I can examine what was loaded, if needed.

> 
> > +	}
> > +
> > +cleanup:
> > +	close(prog_fd);
> > +	close(map_fd);
> > +}
> > +
> > +/*
> > + * Verifier can delete code in two cases: nops & dead code. From insn
> > + * array's point of view, the two cases are the same, so test using
> > + * the simplest method: by loading some nops
> > + */
> > +static void check_deletions(void)
> > +{
> > +	struct bpf_insn insns[] = {
> > +		BPF_MOV64_IMM(BPF_REG_0, 2),
> > +		BPF_JMP_IMM(BPF_JA, 0, 0, 0), /* nop */
> > +		BPF_MOV64_IMM(BPF_REG_0, 1),
> > +		BPF_JMP_IMM(BPF_JA, 0, 0, 0), /* nop */
> > +		BPF_MOV64_IMM(BPF_REG_0, 0),
> > +		BPF_EXIT_INSN(),
> > +	};
> 
> Success test cases follow identical pattern, ultimately having 3 input
> parameters:
> - program
> - map_in
> - map_out
> 
> Would it make sense to write a generic utility function accepting
> exactly these three params and hiding the boilerplate?

Will do.

Are you ok with the contexts of tests? Any more test cases, maybe?

> > +	int prog_fd = -1, map_fd;
> > +	__u32 map_in[] = {0, 1, 2, 3, 4, 5};
> > +	__u32 map_out[] = {0, -1, 1, -1, 2, 3};
> > +	struct bpf_insn_array_value val = {};
> > +	int i;
> > +
> > +	map_fd = map_create(BPF_MAP_TYPE_INSN_ARRAY, ARRAY_SIZE(insns));
> > +	if (!ASSERT_GE(map_fd, 0, "map_create"))
> > +		return;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(insns); i++) {
> > +		val.xlated_off = map_in[i];
> > +		if (!ASSERT_EQ(bpf_map_update_elem(map_fd, &i, &val, 0), 0,
> > +			       "bpf_map_update_elem"))
> > +			goto cleanup;
> > +	}
> > +
> > +	if (!ASSERT_EQ(bpf_map_freeze(map_fd), 0, "bpf_map_freeze"))
> > +		goto cleanup;
> > +
> > +	prog_fd = prog_load(insns, ARRAY_SIZE(insns), &map_fd, 1);
> > +	if (!ASSERT_GE(prog_fd, 0, "bpf(BPF_PROG_LOAD)"))
> > +		goto cleanup;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(insns); i++) {
> > +		if (!ASSERT_EQ(bpf_map_lookup_elem(map_fd, &i, &val), 0, "bpf_map_lookup_elem"))
> > +			goto cleanup;
> > +
> > +		ASSERT_EQ(val.xlated_off, map_out[i], "val should be equal map_out[i]");
> > +	}
> > +
> > +cleanup:
> > +	close(prog_fd);
> > +	close(map_fd);
> > +}
> 
> [...]

  reply	other threads:[~2025-10-03  7:40 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-30 12:50 [PATCH v5 bpf-next 00/15] BPF indirect jumps Anton Protopopov
2025-09-30 12:50 ` [PATCH v5 bpf-next 01/15] bpf: fix the return value of push_stack Anton Protopopov
2025-09-30 12:50 ` [PATCH v5 bpf-next 02/15] bpf: save the start of functions in bpf_prog_aux Anton Protopopov
2025-10-01 21:53   ` Eduard Zingerman
2025-09-30 12:50 ` [PATCH v5 bpf-next 03/15] bpf: generalize and export map_get_next_key for arrays Anton Protopopov
2025-10-01 21:56   ` Eduard Zingerman
2025-09-30 12:51 ` [PATCH v5 bpf-next 04/15] bpf, x86: add new map type: instructions array Anton Protopopov
2025-10-03  0:50   ` Eduard Zingerman
2025-10-03  7:39     ` Anton Protopopov
2025-10-03  8:48       ` Eduard Zingerman
2025-10-03  9:13         ` Anton Protopopov
2025-10-03 17:22           ` Eduard Zingerman
2025-09-30 12:51 ` [PATCH v5 bpf-next 05/15] selftests/bpf: add selftests for new insn_array map Anton Protopopov
2025-10-03  1:16   ` Eduard Zingerman
2025-10-03  7:46     ` Anton Protopopov [this message]
2025-10-03  8:15       ` Eduard Zingerman
2025-09-30 12:51 ` [PATCH v5 bpf-next 06/15] bpf: support instructions arrays with constants blinding Anton Protopopov
2025-10-03 17:38   ` Eduard Zingerman
2025-09-30 12:51 ` [PATCH v5 bpf-next 07/15] selftests/bpf: test instructions arrays with blinding Anton Protopopov
2025-10-03  9:00   ` Eduard Zingerman
2025-09-30 12:51 ` [PATCH v5 bpf-next 08/15] bpf, x86: allow indirect jumps to r8...r15 Anton Protopopov
2025-10-01 22:03   ` Eduard Zingerman
2025-09-30 12:51 ` [PATCH v5 bpf-next 09/15] bpf: make bpf_insn_successors to return a pointer Anton Protopopov
2025-10-01 22:39   ` Eduard Zingerman
2025-10-01 23:49     ` Alexei Starovoitov
2025-10-02  8:19       ` Anton Protopopov
2025-10-02 16:07         ` Alexei Starovoitov
2025-10-02  8:16     ` Anton Protopopov
2025-10-02 19:35       ` Eduard Zingerman
2025-09-30 12:51 ` [PATCH v5 bpf-next 10/15] bpf, x86: add support for indirect jumps Anton Protopopov
2025-10-02  0:15   ` Eduard Zingerman
2025-10-02  9:27     ` Anton Protopopov
2025-10-02 19:52       ` Eduard Zingerman
2025-10-03  7:04         ` Anton Protopopov
2025-09-30 12:51 ` [PATCH v5 bpf-next 11/15] bpf: disasm: add support for BPF_JMP|BPF_JA|BPF_X Anton Protopopov
2025-10-02  0:18   ` Eduard Zingerman
2025-10-02  7:49     ` Anton Protopopov
2025-09-30 12:51 ` [PATCH v5 bpf-next 12/15] libbpf: fix formatting of bpf_object__append_subprog_code Anton Protopopov
2025-09-30 12:51 ` [PATCH v5 bpf-next 13/15] libbpf: support llvm-generated indirect jumps Anton Protopopov
2025-10-02 21:01   ` Eduard Zingerman
2025-10-03  7:19     ` Anton Protopopov
2025-10-15 15:32   ` Yonghong Song
2025-10-15 17:35     ` Anton Protopopov
2025-09-30 12:51 ` [PATCH v5 bpf-next 14/15] bpftool: Recognize insn_array map type Anton Protopopov
2025-09-30 12:51 ` [PATCH v5 bpf-next 15/15] selftests/bpf: add selftests for indirect jumps Anton Protopopov
2025-10-02 21:07   ` Eduard Zingerman
2025-10-03  7:22     ` Anton Protopopov
2025-10-03  7:29       ` Eduard Zingerman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aN9/XoodAYHN5Lm7@mail.gmail.com \
    --to=a.s.protopopov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=aspsk@isovalent.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=qmo@kernel.org \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox