diff options
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.patch | 183 |
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 @@ | |||
1 | From a945df2439020ca182513b6e2f24175cbf2a2dc4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Yonghong Song <yhs@fb.com> | ||
3 | Date: Mon, 6 Jun 2022 23:26:36 -0700 | ||
4 | Subject: [PATCH] libbpf: Add enum64 sanitization | ||
5 | |||
6 | When old kernel does not support enum64 but user space btf | ||
7 | contains non-zero enum kflag or enum64, libbpf needs to | ||
8 | do proper sanitization so modified btf can be accepted | ||
9 | by the kernel. | ||
10 | |||
11 | Sanitization for enum kflag can be achieved by clearing | ||
12 | the kflag bit. For enum64, the type is replaced with an | ||
13 | union of integer member types and the integer member size | ||
14 | must be smaller than enum64 size. If such an integer | ||
15 | type cannot be found, a new type is created and used | ||
16 | for union members. | ||
17 | |||
18 | Acked-by: Andrii Nakryiko <andrii@kernel.org> | ||
19 | Signed-off-by: Yonghong Song <yhs@fb.com> | ||
20 | Link: https://lore.kernel.org/r/20220607062636.3721375-1-yhs@fb.com | ||
21 | Signed-off-by: Alexei Starovoitov <ast@kernel.org> | ||
22 | |||
23 | Upstream-Status: Backport [https://github.com/libbpf/libbpf/commit/a945df2439020ca182513b6e2f24175cbf2a2dc4] | ||
24 | |||
25 | Signed-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 | |||
32 | diff --git a/src/btf.h b/src/btf.h | ||
33 | index 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 | { | ||
48 | diff --git a/src/libbpf.c b/src/libbpf.c | ||
49 | index 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) | ||
169 | diff --git a/src/libbpf_internal.h b/src/libbpf_internal.h | ||
170 | index 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 | -- | ||
183 | 2.40.0 | ||