summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-sanitization.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-sanitization.patch')
-rw-r--r--recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-sanitization.patch183
1 files changed, 183 insertions, 0 deletions
diff --git a/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-sanitization.patch b/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-sanitization.patch
new file mode 100644
index 0000000..e13e0d3
--- /dev/null
+++ b/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-sanitization.patch
@@ -0,0 +1,183 @@
1From a945df2439020ca182513b6e2f24175cbf2a2dc4 Mon Sep 17 00:00:00 2001
2From: Yonghong Song <yhs@fb.com>
3Date: Mon, 6 Jun 2022 23:26:36 -0700
4Subject: [PATCH] libbpf: Add enum64 sanitization
5
6When old kernel does not support enum64 but user space btf
7contains non-zero enum kflag or enum64, libbpf needs to
8do proper sanitization so modified btf can be accepted
9by the kernel.
10
11Sanitization for enum kflag can be achieved by clearing
12the kflag bit. For enum64, the type is replaced with an
13union of integer member types and the integer member size
14must be smaller than enum64 size. If such an integer
15type cannot be found, a new type is created and used
16for union members.
17
18Acked-by: Andrii Nakryiko <andrii@kernel.org>
19Signed-off-by: Yonghong Song <yhs@fb.com>
20Link: https://lore.kernel.org/r/20220607062636.3721375-1-yhs@fb.com
21Signed-off-by: Alexei Starovoitov <ast@kernel.org>
22
23Upstream-Status: Backport [https://github.com/libbpf/libbpf/commit/a945df2439020ca182513b6e2f24175cbf2a2dc4]
24
25Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
26---
27 src/btf.h | 3 ++-
28 src/libbpf.c | 56 +++++++++++++++++++++++++++++++++++++++----
29 src/libbpf_internal.h | 2 ++
30 3 files changed, 56 insertions(+), 5 deletions(-)
31
32diff --git a/src/btf.h b/src/btf.h
33index 951ac74..bddc4b3 100644
34--- a/src/btf.h
35+++ b/src/btf.h
36@@ -393,9 +393,10 @@ btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
37 #ifndef BTF_KIND_FLOAT
38 #define BTF_KIND_FLOAT 16 /* Floating point */
39 #endif
40-/* The kernel header switched to enums, so these two were never #defined */
41+/* The kernel header switched to enums, so the following were never #defined */
42 #define BTF_KIND_DECL_TAG 17 /* Decl Tag */
43 #define BTF_KIND_TYPE_TAG 18 /* Type Tag */
44+#define BTF_KIND_ENUM64 19 /* Enum for up-to 64bit values */
45
46 static inline __u16 btf_kind(const struct btf_type *t)
47 {
48diff --git a/src/libbpf.c b/src/libbpf.c
49index 2262bcd..5321025 100644
50--- a/src/libbpf.c
51+++ b/src/libbpf.c
52@@ -2110,6 +2110,7 @@ static const char *__btf_kind_str(__u16 kind)
53 case BTF_KIND_FLOAT: return "float";
54 case BTF_KIND_DECL_TAG: return "decl_tag";
55 case BTF_KIND_TYPE_TAG: return "type_tag";
56+ case BTF_KIND_ENUM64: return "enum64";
57 default: return "unknown";
58 }
59 }
60@@ -2634,12 +2635,13 @@ static bool btf_needs_sanitization(struct bpf_object *obj)
61 bool has_func = kernel_supports(obj, FEAT_BTF_FUNC);
62 bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG);
63 bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG);
64+ bool has_enum64 = kernel_supports(obj, FEAT_BTF_ENUM64);
65
66 return !has_func || !has_datasec || !has_func_global || !has_float ||
67- !has_decl_tag || !has_type_tag;
68+ !has_decl_tag || !has_type_tag || !has_enum64;
69 }
70
71-static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
72+static int bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
73 {
74 bool has_func_global = kernel_supports(obj, FEAT_BTF_GLOBAL_FUNC);
75 bool has_datasec = kernel_supports(obj, FEAT_BTF_DATASEC);
76@@ -2647,6 +2649,8 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
77 bool has_func = kernel_supports(obj, FEAT_BTF_FUNC);
78 bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG);
79 bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG);
80+ bool has_enum64 = kernel_supports(obj, FEAT_BTF_ENUM64);
81+ __u32 enum64_placeholder_id = 0;
82 struct btf_type *t;
83 int i, j, vlen;
84
85@@ -2709,8 +2713,32 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
86 /* replace TYPE_TAG with a CONST */
87 t->name_off = 0;
88 t->info = BTF_INFO_ENC(BTF_KIND_CONST, 0, 0);
89- }
90+ } else if (!has_enum64 && btf_is_enum(t)) {
91+ /* clear the kflag */
92+ t->info = btf_type_info(btf_kind(t), btf_vlen(t), false);
93+ } else if (!has_enum64 && btf_is_enum64(t)) {
94+ /* replace ENUM64 with a union */
95+ struct btf_member *m;
96+
97+ if (enum64_placeholder_id == 0) {
98+ enum64_placeholder_id = btf__add_int(btf, "enum64_placeholder", 1, 0);
99+ if (enum64_placeholder_id < 0)
100+ return enum64_placeholder_id;
101+
102+ t = (struct btf_type *)btf__type_by_id(btf, i);
103+ }
104+
105+ m = btf_members(t);
106+ vlen = btf_vlen(t);
107+ t->info = BTF_INFO_ENC(BTF_KIND_UNION, 0, vlen);
108+ for (j = 0; j < vlen; j++, m++) {
109+ m->type = enum64_placeholder_id;
110+ m->offset = 0;
111+ }
112+ }
113 }
114+
115+ return 0;
116 }
117
118 static bool libbpf_needs_btf(const struct bpf_object *obj)
119@@ -3008,7 +3036,9 @@ static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj)
120
121 /* enforce 8-byte pointers for BPF-targeted BTFs */
122 btf__set_pointer_size(obj->btf, 8);
123- bpf_object__sanitize_btf(obj, kern_btf);
124+ err = bpf_object__sanitize_btf(obj, kern_btf);
125+ if (err)
126+ return err;
127 }
128
129 if (obj->gen_loader) {
130@@ -3515,6 +3545,10 @@ static enum kcfg_type find_kcfg_type(const struct btf *btf, int id,
131 if (strcmp(name, "libbpf_tristate"))
132 return KCFG_UNKNOWN;
133 return KCFG_TRISTATE;
134+ case BTF_KIND_ENUM64:
135+ if (strcmp(name, "libbpf_tristate"))
136+ return KCFG_UNKNOWN;
137+ return KCFG_TRISTATE;
138 case BTF_KIND_ARRAY:
139 if (btf_array(t)->nelems == 0)
140 return KCFG_UNKNOWN;
141@@ -4662,6 +4696,17 @@ static int probe_perf_link(void)
142 return link_fd < 0 && err == -EBADF;
143 }
144
145+static int probe_kern_btf_enum64(void)
146+{
147+ static const char strs[] = "\0enum64";
148+ __u32 types[] = {
149+ BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8),
150+ };
151+
152+ return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
153+ strs, sizeof(strs)));
154+}
155+
156 enum kern_feature_result {
157 FEAT_UNKNOWN = 0,
158 FEAT_SUPPORTED = 1,
159@@ -4724,6 +4769,9 @@ static struct kern_feature_desc {
160 [FEAT_MEMCG_ACCOUNT] = {
161 "memcg-based memory accounting", probe_memcg_account,
162 },
163+ [FEAT_BTF_ENUM64] = {
164+ "BTF_KIND_ENUM64 support", probe_kern_btf_enum64,
165+ },
166 };
167
168 bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id)
169diff --git a/src/libbpf_internal.h b/src/libbpf_internal.h
170index bc86b82..2b72531 100644
171--- a/src/libbpf_internal.h
172+++ b/src/libbpf_internal.h
173@@ -329,6 +329,8 @@ enum kern_feature_id {
174 FEAT_BTF_TYPE_TAG,
175 /* memcg-based accounting for BPF maps and progs */
176 FEAT_MEMCG_ACCOUNT,
177+ /* BTF_KIND_ENUM64 support and BTF_KIND_ENUM kflag support */
178+ FEAT_BTF_ENUM64,
179 __FEAT_CNT,
180 };
181
182--
1832.40.0