1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2023. Huawei Technologies Co., Ltd */
3#include <linux/types.h>
4#include <bpf/bpf_helpers.h>
5
6#include "bpf_experimental.h"
7#include "bpf_misc.h"
8
9char _license[] SEC("license") = "GPL";
10
11struct bin_data {
12	char blob[32];
13};
14
15#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
16private(kptr) struct bin_data __kptr * ptr;
17
18SEC("tc")
19__naked int kptr_xchg_inline(void)
20{
21	asm volatile (
22		"r1 = %[ptr] ll;"
23		"r2 = 0;"
24		"call %[bpf_kptr_xchg];"
25		"if r0 == 0 goto 1f;"
26		"r1 = r0;"
27		"r2 = 0;"
28		"call %[bpf_obj_drop_impl];"
29	"1:"
30		"r0 = 0;"
31		"exit;"
32		:
33		: __imm_addr(ptr),
34		  __imm(bpf_kptr_xchg),
35		  __imm(bpf_obj_drop_impl)
36		: __clobber_all
37	);
38}
39
40/* BTF FUNC records are not generated for kfuncs referenced
41 * from inline assembly. These records are necessary for
42 * libbpf to link the program. The function below is a hack
43 * to ensure that BTF FUNC records are generated.
44 */
45void __btf_root(void)
46{
47	bpf_obj_drop(NULL);
48}
49