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 
9 char _license[] SEC("license") = "GPL";
10 
11 struct bin_data {
12 	char blob[32];
13 };
14 
15 #define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
16 private(kptr) struct bin_data __kptr * ptr;
17 
18 SEC("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  */
45 void __btf_root(void)
46 {
47 	bpf_obj_drop(NULL);
48 }
49