On Mon Jun 15, 2026 at 8:26 AM PDT, Leon Hwang wrote:
> Add a test to verify global percpu data related xlated insns:
>
> 1. ld_imm64: compare xlated one with the one in ELF object file.
> 2. mov64_percpu_reg: it is added by verifier.
>
> Signed-off-by: Leon Hwang <[email protected]>
> ---
>  .../bpf/prog_tests/global_data_init.c         | 87 +++++++++++++++++++
>  .../bpf/progs/test_global_percpu_data.c       | 11 +++
>  2 files changed, 98 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/global_data_init.c 
> b/tools/testing/selftests/bpf/prog_tests/global_data_init.c
> index e4c290492ff8..fcc2c4ec8644 100644
> --- a/tools/testing/selftests/bpf/prog_tests/global_data_init.c
> +++ b/tools/testing/selftests/bpf/prog_tests/global_data_init.c
> @@ -279,6 +279,91 @@ static void test_global_percpu_data_verifier_log(void)
>       RUN_TESTS(test_global_percpu_data);
>  }
>  
> +static int find_ld_imm64(const struct bpf_insn *insns, size_t insn_cnt, 
> struct bpf_insn *ld_imm64)
> +{
> +     size_t i;
> +
> +     for (i = 0; i < insn_cnt; i++) {
> +             if (insns[i].code == (BPF_LD | BPF_IMM | BPF_DW)) {
> +                     ld_imm64[0] = insns[i];
> +                     ld_imm64[1] = insns[i + 1];
> +                     return i;
> +             }
> +     }
> +
> +     return -ENOENT;
> +}
> +
> +/*
> + * Special (internal-only) form of mov, used to resolve per-CPU addrs:
> + * dst_reg = src_reg + <percpu_base_off>
> + * BPF_ADDR_PERCPU is used as a special insn->off value.
> + */
> +#define BPF_ADDR_PERCPU      (-1)
> +
> +#define BPF_MOV64_PERCPU_REG(DST, SRC)                               \
> +     ((struct bpf_insn) {                                    \
> +             .code  = BPF_ALU64 | BPF_MOV | BPF_X,           \
> +             .dst_reg = DST,                                 \
> +             .src_reg = SRC,                                 \
> +             .off   = BPF_ADDR_PERCPU,                       \
> +             .imm   = 0 })
> +
> +static __u64 ld_imm64_to_u64(const struct bpf_insn *insn)
> +{
> +     return ((__u64)(__u32) insn[1].imm << 32) | (__u32) insn[0].imm;
> +}
> +
> +static void test_global_percpu_data_xlated(void)
> +{
> +     struct bpf_insn ld_imm64_raw[2], ld_imm64_xlated[2], mov64_percpu_reg, 
> *insns = NULL;
> +     size_t insn_sz = sizeof(struct bpf_insn);
> +     struct test_global_percpu_data *skel;
> +     struct bpf_program *prog;
> +     int idx, err;
> +     __u32 cnt;
> +
> +     skel = test_global_percpu_data__open();
> +     if (!ASSERT_OK_PTR(skel, "test_global_percpu_data__open"))
> +             return;
> +
> +     prog = skel->progs.verifier_percpu_read;
> +     idx = find_ld_imm64(bpf_program__insns(prog), 
> bpf_program__insn_cnt(prog), ld_imm64_raw);
> +     if (!ASSERT_GE(idx, 0, "find_ld_imm64 raw"))
> +             goto out;
> +
> +     err = test_global_percpu_data__load(skel);
> +     if (!ASSERT_OK(err, "test_global_percpu_data__load"))
> +             goto out;
> +
> +     err = get_xlated_program(bpf_program__fd(prog), &insns, &cnt);
> +     if (!ASSERT_OK(err, "get_xlated_program"))
> +             goto out;
> +
> +     idx = find_ld_imm64(insns, cnt, ld_imm64_xlated);
> +     if (!ASSERT_GE(idx, 0, "find_ld_imm64 xlated"))
> +             goto out;
> +
> +     if (!ASSERT_GT(cnt, idx + 2, "xlated insn count"))
> +             goto out;
> +
> +     ASSERT_EQ(ld_imm64_xlated[0].code, ld_imm64_raw[0].code, "ld_imm64 
> opcode");
> +     ASSERT_TRUE(ld_imm64_xlated[0].dst_reg == ld_imm64_raw[0].dst_reg, 
> "ld_imm64 dst_reg");
> +     /*
> +      * The xlated instruction has the map ID in imm and the offset
> +      * in the next instruction's imm. The raw instruction just has
> +      * the offset in its imm.
> +      */
> +     ASSERT_EQ(ld_imm64_xlated[1].imm, ld_imm64_to_u64(ld_imm64_raw), 
> "ld_imm64 off");
> +
> +     mov64_percpu_reg = BPF_MOV64_PERCPU_REG(ld_imm64_raw[0].dst_reg, 
> ld_imm64_raw[0].dst_reg);
> +     ASSERT_MEMEQ(&insns[idx + 2], &mov64_percpu_reg, insn_sz, 
> "mov64_percpu_reg");

If the point of the test was to check that percpu_array_map_direct_value_meta()
computes 'off' correctly then it failed to achieve that goal.
It checks that map ID is correct which is a pointless test.
Either make it a real test or drop this patch.

pw-bot: cr

Reply via email to