On 3/18/25 7:33 AM, Anton Protopopov wrote:
Add self-tests to test new BPF_STATIC_BRANCH_JA jump instructions and the BPF_STATIC_KEY_UPDATE syscall. Signed-off-by: Anton Protopopov <aspsk@xxxxxxxxxxxxx> --- .../bpf/prog_tests/bpf_static_keys.c | 359 ++++++++++++++++++ .../selftests/bpf/progs/bpf_static_keys.c | 131 +++++++ 2 files changed, 490 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/bpf_static_keys.c create mode 100644 tools/testing/selftests/bpf/progs/bpf_static_keys.c diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_static_keys.c b/tools/testing/selftests/bpf/prog_tests/bpf_static_keys.c new file mode 100644 index 000000000000..3f105d36743b --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/bpf_static_keys.c @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <test_progs.h> + +#include <sys/syscall.h> +#include <bpf/bpf.h> + +#include "bpf_static_keys.skel.h" + +#define VAL_ON 7 +#define VAL_OFF 3 + +enum { + OFF, + ON +}; + +static int _bpf_prog_load(struct bpf_insn *insns, __u32 insn_cnt) +{ + return bpf_prog_load(BPF_PROG_TYPE_XDP, NULL, "GPL", insns, insn_cnt, NULL); +} + +static int _bpf_static_key_update(int map_fd, __u32 on) +{ + LIBBPF_OPTS(bpf_static_key_update_opts, opts); + + opts.on = on; + + return bpf_static_key_update(map_fd, &opts); +} + +#define BPF_JMP32_OR_NOP(IMM, OFF) \ + ((struct bpf_insn) { \ + .code = BPF_JMP32 | BPF_JA | BPF_K, \ + .dst_reg = 0, \ + .src_reg = BPF_STATIC_BRANCH_JA, \ + .off = OFF, \ + .imm = IMM }) + +#define BPF_JMP_OR_NOP(IMM, OFF) \ + ((struct bpf_insn) { \ + .code = BPF_JMP | BPF_JA | BPF_K, \ + .dst_reg = 0, \ + .src_reg = BPF_STATIC_BRANCH_JA, \ + .off = OFF, \ + .imm = IMM }) + +#define BPF_NOP_OR_JMP32(IMM, OFF) \ + ((struct bpf_insn) { \ + .code = BPF_JMP32 | BPF_JA | BPF_K, \ + .dst_reg = 0, \ + .src_reg = BPF_STATIC_BRANCH_JA | \ + BPF_STATIC_BRANCH_NOP, \ + .off = OFF, \ + .imm = IMM }) + +#define BPF_NOP_OR_JMP(IMM, OFF) \ + ((struct bpf_insn) { \ + .code = BPF_JMP | BPF_JA | BPF_K, \ + .dst_reg = 0, \ + .src_reg = BPF_STATIC_BRANCH_JA | \ + BPF_STATIC_BRANCH_NOP, \ + .off = OFF, \ + .imm = IMM }) + +static const struct bpf_insn insns0[] = { + BPF_JMP_OR_NOP(0, 1), + BPF_NOP_OR_JMP(0, 1), + BPF_JMP32_OR_NOP(1, 0), + BPF_NOP_OR_JMP32(1, 0), +}; +
[...]
+ +static void check_bpf_to_bpf_call(struct bpf_static_keys *skel, + struct bpf_map *key1, + struct bpf_map *key2) +{ + struct bpf_link *link; + + link = bpf_program__attach(skel->progs.check_bpf_to_bpf_call);
there is no progcheck_bpf_to_bpf_call. Compilation will fail.
+ if (!ASSERT_OK_PTR(link, "link")) + return; + + __check_multiple_keys(skel, key1, key2, 0, 303, 3030, 3333); + + bpf_link__destroy(link); +} +
[...]