117bda53eSHou Tao // SPDX-License-Identifier: GPL-2.0
217bda53eSHou Tao /* Copyright (C) 2023. Huawei Technologies Co., Ltd */
317bda53eSHou Tao #include <test_progs.h>
417bda53eSHou Tao
517bda53eSHou Tao #include "linux/filter.h"
617bda53eSHou Tao #include "kptr_xchg_inline.skel.h"
717bda53eSHou Tao
test_kptr_xchg_inline(void)817bda53eSHou Tao void test_kptr_xchg_inline(void)
917bda53eSHou Tao {
1017bda53eSHou Tao struct kptr_xchg_inline *skel;
1117bda53eSHou Tao struct bpf_insn *insn = NULL;
1217bda53eSHou Tao struct bpf_insn exp;
1317bda53eSHou Tao unsigned int cnt;
1417bda53eSHou Tao int err;
1517bda53eSHou Tao
16994ff2f7SPu Lehui #if !(defined(__x86_64__) || defined(__aarch64__) || \
17994ff2f7SPu Lehui (defined(__riscv) && __riscv_xlen == 64))
1817bda53eSHou Tao test__skip();
1917bda53eSHou Tao return;
2017bda53eSHou Tao #endif
2117bda53eSHou Tao
2217bda53eSHou Tao skel = kptr_xchg_inline__open_and_load();
2317bda53eSHou Tao if (!ASSERT_OK_PTR(skel, "open_load"))
2417bda53eSHou Tao return;
2517bda53eSHou Tao
2617bda53eSHou Tao err = get_xlated_program(bpf_program__fd(skel->progs.kptr_xchg_inline), &insn, &cnt);
2717bda53eSHou Tao if (!ASSERT_OK(err, "prog insn"))
2817bda53eSHou Tao goto out;
2917bda53eSHou Tao
3017bda53eSHou Tao /* The original instructions are:
3117bda53eSHou Tao * r1 = map[id:xxx][0]+0
3217bda53eSHou Tao * r2 = 0
3317bda53eSHou Tao * call bpf_kptr_xchg#yyy
3417bda53eSHou Tao *
3517bda53eSHou Tao * call bpf_kptr_xchg#yyy will be inlined as:
3617bda53eSHou Tao * r0 = r2
3717bda53eSHou Tao * r0 = atomic64_xchg((u64 *)(r1 +0), r0)
3817bda53eSHou Tao */
3917bda53eSHou Tao if (!ASSERT_GT(cnt, 5, "insn cnt"))
4017bda53eSHou Tao goto out;
4117bda53eSHou Tao
4217bda53eSHou Tao exp = BPF_MOV64_REG(BPF_REG_0, BPF_REG_2);
4317bda53eSHou Tao if (!ASSERT_OK(memcmp(&insn[3], &exp, sizeof(exp)), "mov"))
4417bda53eSHou Tao goto out;
4517bda53eSHou Tao
4617bda53eSHou Tao exp = BPF_ATOMIC_OP(BPF_DW, BPF_XCHG, BPF_REG_1, BPF_REG_0, 0);
4717bda53eSHou Tao if (!ASSERT_OK(memcmp(&insn[4], &exp, sizeof(exp)), "xchg"))
4817bda53eSHou Tao goto out;
4917bda53eSHou Tao out:
5017bda53eSHou Tao free(insn);
5117bda53eSHou Tao kptr_xchg_inline__destroy(skel);
5217bda53eSHou Tao }
53