From 2b21544ca797b91f1739c965cf620c245766e309 Mon Sep 17 00:00:00 2001 From: Soumya Sambu Date: Tue, 18 Mar 2025 10:31:38 +0000 Subject: bpftrace: Fix llvm-objcopy issue and backport libbpf patches for kirkstone-clang18 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix bpftrace do_configure failure for kirkstone-clang18: | CMake Error at tests/data/CMakeLists.txt:6 (find_program): | Could not find LLVM_OBJCOPY using the following names: llvm-objcopy, | llvm-objcopy-18, llvm18-objcopy This error occurs because bpftrace searches for llvm-objcopy-${LLVM_VERSION_MAJOR}, expecting llvm version 18.x, while llvm-native from oe-core provides v13.0.1. Since clang-native provides v18.1.6, switching to it resolves the issue. While fixing this, additional libbpf compatibility issues were identified during bpftrace compilation, requiring backporting of multiple patches to resolve: • Undefined BTF_KIND_ENUM64, replaced with BTF_KIND_ENUM. • Missing kprobe_multi in bpf_link_create_opts. • Undefined BPF_TRACE_KPROBE_MULTI. • Undefined reference to btf_is_enum64 in libbpf.so and other related libbpf errors Signed-off-by: Soumya Sambu --- .../recipes-devtools/bpftrace/bpftrace_0.20.1.bb | 2 +- .../libbpf/0001-bpf-Add-btf-enum64-support.patch | 113 ++++++++++ ...kie-support-to-programs-attached-with-kpr.patch | 44 ++++ .../libbpf/0001-bpf-Add-multi-kprobe-link.patch | 91 ++++++++ ...bpf_link_create-support-for-multi-kprobes.patch | 65 ++++++ ...-enum64-parsing-and-new-enum64-public-API.patch | 250 +++++++++++++++++++++ .../0001-libbpf-Add-enum64-sanitization.patch | 183 +++++++++++++++ ...ctor-btf__add_enum-for-future-code-sharin.patch | 83 +++++++ recipes-kernel/libbpf/libbpf_%.bbappend | 9 +- 9 files changed, 838 insertions(+), 2 deletions(-) create mode 100644 recipes-kernel/libbpf/libbpf/0001-bpf-Add-btf-enum64-support.patch create mode 100644 recipes-kernel/libbpf/libbpf/0001-bpf-Add-cookie-support-to-programs-attached-with-kpr.patch create mode 100644 recipes-kernel/libbpf/libbpf/0001-bpf-Add-multi-kprobe-link.patch create mode 100644 recipes-kernel/libbpf/libbpf/0001-libbpf-Add-bpf_link_create-support-for-multi-kprobes.patch create mode 100644 recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-parsing-and-new-enum64-public-API.patch create mode 100644 recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-sanitization.patch create mode 100644 recipes-kernel/libbpf/libbpf/0001-libbpf-Refactor-btf__add_enum-for-future-code-sharin.patch diff --git a/dynamic-layers/openembedded-layer/recipes-devtools/bpftrace/bpftrace_0.20.1.bb b/dynamic-layers/openembedded-layer/recipes-devtools/bpftrace/bpftrace_0.20.1.bb index 355f427..1bd9150 100644 --- a/dynamic-layers/openembedded-layer/recipes-devtools/bpftrace/bpftrace_0.20.1.bb +++ b/dynamic-layers/openembedded-layer/recipes-devtools/bpftrace/bpftrace_0.20.1.bb @@ -12,7 +12,7 @@ DEPENDS += "bison-native \ libcereal \ libbpf \ " -DEPENDS += "${@bb.utils.contains('PTEST_ENABLED', '1', 'pahole-native llvm-native', '', d)}" +DEPENDS += "${@bb.utils.contains('PTEST_ENABLED', '1', 'pahole-native clang-native', '', d)}" RDEPENDS:${PN} += "bash python3 xz" diff --git a/recipes-kernel/libbpf/libbpf/0001-bpf-Add-btf-enum64-support.patch b/recipes-kernel/libbpf/libbpf/0001-bpf-Add-btf-enum64-support.patch new file mode 100644 index 0000000..2c510f0 --- /dev/null +++ b/recipes-kernel/libbpf/libbpf/0001-bpf-Add-btf-enum64-support.patch @@ -0,0 +1,113 @@ +From 9a976c6b98de8da85341b341adb9be5b9850ad10 Mon Sep 17 00:00:00 2001 +From: Yonghong Song +Date: Mon, 6 Jun 2022 23:26:00 -0700 +Subject: [PATCH] bpf: Add btf enum64 support + +Currently, BTF only supports upto 32bit enum value with BTF_KIND_ENUM. +But in kernel, some enum indeed has 64bit values, e.g., +in uapi bpf.h, we have + enum { + BPF_F_INDEX_MASK = 0xffffffffULL, + BPF_F_CURRENT_CPU = BPF_F_INDEX_MASK, + BPF_F_CTXLEN_MASK = (0xfffffULL << 32), + }; +In this case, BTF_KIND_ENUM will encode the value of BPF_F_CTXLEN_MASK +as 0, which certainly is incorrect. + +This patch added a new btf kind, BTF_KIND_ENUM64, which permits +64bit value to cover the above use case. The BTF_KIND_ENUM64 has +the following three fields followed by the common type: + struct bpf_enum64 { + __u32 nume_off; + __u32 val_lo32; + __u32 val_hi32; + }; +Currently, btf type section has an alignment of 4 as all element types +are u32. Representing the value with __u64 will introduce a pad +for bpf_enum64 and may also introduce misalignment for the 64bit value. +Hence, two members of val_hi32 and val_lo32 are chosen to avoid these issues. + +The kflag is also introduced for BTF_KIND_ENUM and BTF_KIND_ENUM64 +to indicate whether the value is signed or unsigned. The kflag intends +to provide consistent output of BTF C fortmat with the original +source code. For example, the original BTF_KIND_ENUM bit value is 0xffffffff. +The format C has two choices, printing out 0xffffffff or -1 and current libbpf +prints out as unsigned value. But if the signedness is preserved in btf, +the value can be printed the same as the original source code. +The kflag value 0 means unsigned values, which is consistent to the default +by libbpf and should also cover most cases as well. + +The new BTF_KIND_ENUM64 is intended to support the enum value represented as +64bit value. But it can represent all BTF_KIND_ENUM values as well. +The compiler ([1]) and pahole will generate BTF_KIND_ENUM64 only if the value has +to be represented with 64 bits. + +In addition, a static inline function btf_kind_core_compat() is introduced which +will be used later when libbpf relo_core.c changed. Here the kernel shares the +same relo_core.c with libbpf. + + [1] https://reviews.llvm.org/D124641 + +Acked-by: Andrii Nakryiko +Signed-off-by: Yonghong Song +Link: https://lore.kernel.org/r/20220607062600.3716578-1-yhs@fb.com +Signed-off-by: Alexei Starovoitov + +Upstream-Status: Backport [https://github.com/libbpf/libbpf/commit/9a976c6b98de8da85341b341adb9be5b9850ad10] + +Signed-off-by: Soumya Sambu +--- + include/uapi/linux/btf.h | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h +index b0d8fea..9932126 100644 +--- a/include/uapi/linux/btf.h ++++ b/include/uapi/linux/btf.h +@@ -36,10 +36,10 @@ struct btf_type { + * bits 24-27: kind (e.g. int, ptr, array...etc) + * bits 28-30: unused + * bit 31: kind_flag, currently used by +- * struct, union and fwd ++ * struct, union, enum, fwd and enum64 + */ + __u32 info; +- /* "size" is used by INT, ENUM, STRUCT, UNION and DATASEC. ++ /* "size" is used by INT, ENUM, STRUCT, UNION, DATASEC and ENUM64. + * "size" tells the size of the type it is describing. + * + * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, +@@ -63,7 +63,7 @@ enum { + BTF_KIND_ARRAY = 3, /* Array */ + BTF_KIND_STRUCT = 4, /* Struct */ + BTF_KIND_UNION = 5, /* Union */ +- BTF_KIND_ENUM = 6, /* Enumeration */ ++ BTF_KIND_ENUM = 6, /* Enumeration up to 32-bit values */ + BTF_KIND_FWD = 7, /* Forward */ + BTF_KIND_TYPEDEF = 8, /* Typedef */ + BTF_KIND_VOLATILE = 9, /* Volatile */ +@@ -76,6 +76,7 @@ enum { + BTF_KIND_FLOAT = 16, /* Floating point */ + BTF_KIND_DECL_TAG = 17, /* Decl Tag */ + BTF_KIND_TYPE_TAG = 18, /* Type Tag */ ++ BTF_KIND_ENUM64 = 19, /* Enumeration up to 64-bit values */ + + NR_BTF_KINDS, + BTF_KIND_MAX = NR_BTF_KINDS - 1, +@@ -186,4 +187,14 @@ struct btf_decl_tag { + __s32 component_idx; + }; + ++/* BTF_KIND_ENUM64 is followed by multiple "struct btf_enum64". ++ * The exact number of btf_enum64 is stored in the vlen (of the ++ * info in "struct btf_type"). ++ */ ++struct btf_enum64 { ++ __u32 name_off; ++ __u32 val_lo32; ++ __u32 val_hi32; ++}; ++ + #endif /* _UAPI__LINUX_BTF_H__ */ +-- +2.40.0 diff --git a/recipes-kernel/libbpf/libbpf/0001-bpf-Add-cookie-support-to-programs-attached-with-kpr.patch b/recipes-kernel/libbpf/libbpf/0001-bpf-Add-cookie-support-to-programs-attached-with-kpr.patch new file mode 100644 index 0000000..3b03545 --- /dev/null +++ b/recipes-kernel/libbpf/libbpf/0001-bpf-Add-cookie-support-to-programs-attached-with-kpr.patch @@ -0,0 +1,44 @@ +From 50ae8c25d225c79f711e2484ccd15d9a4c228470 Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Wed, 16 Mar 2022 13:24:12 +0100 +Subject: [PATCH] bpf: Add cookie support to programs attached with kprobe + multi link + +Adding support to call bpf_get_attach_cookie helper from +kprobe programs attached with kprobe multi link. + +The cookie is provided by array of u64 values, where each +value is paired with provided function address or symbol +with the same array index. + +When cookie array is provided it's sorted together with +addresses (check bpf_kprobe_multi_cookie_swap). This way +we can find cookie based on the address in +bpf_get_attach_cookie helper. + +Suggested-by: Andrii Nakryiko +Signed-off-by: Jiri Olsa +Signed-off-by: Alexei Starovoitov +Link: https://lore.kernel.org/bpf/20220316122419.933957-7-jolsa@kernel.org + +Upstream-Status: Backport [https://github.com/libbpf/libbpf/commit/50ae8c25d225c79f711e2484ccd15d9a4c228470] + +Signed-off-by: Soumya Sambu +--- + include/uapi/linux/bpf.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index 39a32fc..5413a84 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -1484,6 +1484,7 @@ union bpf_attr { + __u32 cnt; + __aligned_u64 syms; + __aligned_u64 addrs; ++ __aligned_u64 cookies; + } kprobe_multi; + }; + } link_create; +-- +2.40.0 diff --git a/recipes-kernel/libbpf/libbpf/0001-bpf-Add-multi-kprobe-link.patch b/recipes-kernel/libbpf/libbpf/0001-bpf-Add-multi-kprobe-link.patch new file mode 100644 index 0000000..b8d6caf --- /dev/null +++ b/recipes-kernel/libbpf/libbpf/0001-bpf-Add-multi-kprobe-link.patch @@ -0,0 +1,91 @@ +From e85e26492d2c10029c6fe66b6d318a05fffe8b10 Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Wed, 16 Mar 2022 13:24:09 +0100 +Subject: [PATCH] bpf: Add multi kprobe link + +Adding new link type BPF_LINK_TYPE_KPROBE_MULTI that attaches kprobe +program through fprobe API. + +The fprobe API allows to attach probe on multiple functions at once +very fast, because it works on top of ftrace. On the other hand this +limits the probe point to the function entry or return. + +The kprobe program gets the same pt_regs input ctx as when it's attached +through the perf API. + +Adding new attach type BPF_TRACE_KPROBE_MULTI that allows attachment +kprobe to multiple function with new link. + +User provides array of addresses or symbols with count to attach the +kprobe program to. The new link_create uapi interface looks like: + + struct { + __u32 flags; + __u32 cnt; + __aligned_u64 syms; + __aligned_u64 addrs; + } kprobe_multi; + +The flags field allows single BPF_TRACE_KPROBE_MULTI bit to create +return multi kprobe. + +Signed-off-by: Masami Hiramatsu +Signed-off-by: Jiri Olsa +Signed-off-by: Alexei Starovoitov +Acked-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20220316122419.933957-4-jolsa@kernel.org + +Upstream-Status: Backport [https://github.com/libbpf/libbpf/commit/e85e26492d2c10029c6fe66b6d318a05fffe8b10] + +Signed-off-by: Soumya Sambu +--- + include/uapi/linux/bpf.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index a7f0dde..39a32fc 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -997,6 +997,7 @@ enum bpf_attach_type { + BPF_SK_REUSEPORT_SELECT, + BPF_SK_REUSEPORT_SELECT_OR_MIGRATE, + BPF_PERF_EVENT, ++ BPF_TRACE_KPROBE_MULTI, + __MAX_BPF_ATTACH_TYPE + }; + +@@ -1011,6 +1012,7 @@ enum bpf_link_type { + BPF_LINK_TYPE_NETNS = 5, + BPF_LINK_TYPE_XDP = 6, + BPF_LINK_TYPE_PERF_EVENT = 7, ++ BPF_LINK_TYPE_KPROBE_MULTI = 8, + + MAX_BPF_LINK_TYPE, + }; +@@ -1118,6 +1120,11 @@ enum bpf_link_type { + */ + #define BPF_F_XDP_HAS_FRAGS (1U << 5) + ++/* link_create.kprobe_multi.flags used in LINK_CREATE command for ++ * BPF_TRACE_KPROBE_MULTI attach type to create return probe. ++ */ ++#define BPF_F_KPROBE_MULTI_RETURN (1U << 0) ++ + /* When BPF ldimm64's insn[0].src_reg != 0 then this can have + * the following extensions: + * +@@ -1472,6 +1479,12 @@ union bpf_attr { + */ + __u64 bpf_cookie; + } perf_event; ++ struct { ++ __u32 flags; ++ __u32 cnt; ++ __aligned_u64 syms; ++ __aligned_u64 addrs; ++ } kprobe_multi; + }; + } link_create; + +-- +2.40.0 diff --git a/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-bpf_link_create-support-for-multi-kprobes.patch b/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-bpf_link_create-support-for-multi-kprobes.patch new file mode 100644 index 0000000..301d599 --- /dev/null +++ b/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-bpf_link_create-support-for-multi-kprobes.patch @@ -0,0 +1,65 @@ +From 2e6e39ef809a64e0c77e7027e9231059a78677fb Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Wed, 16 Mar 2022 13:24:14 +0100 +Subject: [PATCH] libbpf: Add bpf_link_create support for multi kprobes + +Adding new kprobe_multi struct to bpf_link_create_opts object +to pass multiple kprobe data to link_create attr uapi. + +Signed-off-by: Jiri Olsa +Signed-off-by: Alexei Starovoitov +Link: https://lore.kernel.org/bpf/20220316122419.933957-9-jolsa@kernel.org + +Upstream-Status: Backport [https://github.com/libbpf/libbpf/commit/2e6e39ef809a64e0c77e7027e9231059a78677fb] + +Signed-off-by: Soumya Sambu +--- + src/bpf.c | 9 +++++++++ + src/bpf.h | 9 ++++++++- + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/bpf.c b/src/bpf.c +index 7f4f4f7..9110a72 100644 +--- a/src/bpf.c ++++ b/src/bpf.c +@@ -853,6 +853,15 @@ int bpf_link_create(int prog_fd, int target_fd, + if (!OPTS_ZEROED(opts, perf_event)) + return libbpf_err(-EINVAL); + break; ++ case BPF_TRACE_KPROBE_MULTI: ++ attr.link_create.kprobe_multi.flags = OPTS_GET(opts, kprobe_multi.flags, 0); ++ attr.link_create.kprobe_multi.cnt = OPTS_GET(opts, kprobe_multi.cnt, 0); ++ attr.link_create.kprobe_multi.syms = ptr_to_u64(OPTS_GET(opts, kprobe_multi.syms, 0)); ++ attr.link_create.kprobe_multi.addrs = ptr_to_u64(OPTS_GET(opts, kprobe_multi.addrs, 0)); ++ attr.link_create.kprobe_multi.cookies = ptr_to_u64(OPTS_GET(opts, kprobe_multi.cookies, 0)); ++ if (!OPTS_ZEROED(opts, kprobe_multi)) ++ return libbpf_err(-EINVAL); ++ break; + default: + if (!OPTS_ZEROED(opts, flags)) + return libbpf_err(-EINVAL); +diff --git a/src/bpf.h b/src/bpf.h +index 7e7f78e..ef6d3e2 100644 +--- a/src/bpf.h ++++ b/src/bpf.h +@@ -413,10 +413,17 @@ struct bpf_link_create_opts { + struct { + __u64 bpf_cookie; + } perf_event; ++ struct { ++ __u32 flags; ++ __u32 cnt; ++ const char **syms; ++ const unsigned long *addrs; ++ const __u64 *cookies; ++ } kprobe_multi; + }; + size_t :0; + }; +-#define bpf_link_create_opts__last_field perf_event ++#define bpf_link_create_opts__last_field kprobe_multi.cookies + + LIBBPF_API int bpf_link_create(int prog_fd, int target_fd, + enum bpf_attach_type attach_type, +-- +2.40.0 diff --git a/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-parsing-and-new-enum64-public-API.patch b/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-parsing-and-new-enum64-public-API.patch new file mode 100644 index 0000000..055ada6 --- /dev/null +++ b/recipes-kernel/libbpf/libbpf/0001-libbpf-Add-enum64-parsing-and-new-enum64-public-API.patch @@ -0,0 +1,250 @@ +From c3f8eecb16ad02ebb3a41a31349f1b851cebe46b Mon Sep 17 00:00:00 2001 +From: Yonghong Song +Date: Mon, 6 Jun 2022 23:26:21 -0700 +Subject: [PATCH] libbpf: Add enum64 parsing and new enum64 public API + +Add enum64 parsing support and two new enum64 public APIs: + btf__add_enum64 + btf__add_enum64_value + +Also add support of signedness for BTF_KIND_ENUM. The +BTF_KIND_ENUM API signatures are not changed. The signedness +will be changed from unsigned to signed if btf__add_enum_value() +finds any negative values. + +Acked-by: Andrii Nakryiko +Signed-off-by: Yonghong Song +Link: https://lore.kernel.org/r/20220607062621.3719391-1-yhs@fb.com +Signed-off-by: Alexei Starovoitov + +Upstream-Status: Backport [https://github.com/libbpf/libbpf/commit/c3f8eecb16ad02ebb3a41a31349f1b851cebe46b] + +Signed-off-by: Soumya Sambu +--- + src/btf.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++ + src/btf.h | 12 ++++++ + src/libbpf.map | 2 + + 3 files changed, 117 insertions(+) + +diff --git a/src/btf.c b/src/btf.c +index 5e0bf3c..bcaad6e 100644 +--- a/src/btf.c ++++ b/src/btf.c +@@ -305,6 +305,8 @@ static int btf_type_size(const struct btf_type *t) + return base_size + sizeof(__u32); + case BTF_KIND_ENUM: + return base_size + vlen * sizeof(struct btf_enum); ++ case BTF_KIND_ENUM64: ++ return base_size + vlen * sizeof(struct btf_enum64); + case BTF_KIND_ARRAY: + return base_size + sizeof(struct btf_array); + case BTF_KIND_STRUCT: +@@ -334,6 +336,7 @@ static void btf_bswap_type_base(struct btf_type *t) + static int btf_bswap_type_rest(struct btf_type *t) + { + struct btf_var_secinfo *v; ++ struct btf_enum64 *e64; + struct btf_member *m; + struct btf_array *a; + struct btf_param *p; +@@ -361,6 +364,13 @@ static int btf_bswap_type_rest(struct btf_type *t) + e->val = bswap_32(e->val); + } + return 0; ++ case BTF_KIND_ENUM64: ++ for (i = 0, e64 = btf_enum64(t); i < vlen; i++, e64++) { ++ e64->name_off = bswap_32(e64->name_off); ++ e64->val_lo32 = bswap_32(e64->val_lo32); ++ e64->val_hi32 = bswap_32(e64->val_hi32); ++ } ++ return 0; + case BTF_KIND_ARRAY: + a = btf_array(t); + a->type = bswap_32(a->type); +@@ -597,6 +607,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id) + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: + case BTF_KIND_ENUM: ++ case BTF_KIND_ENUM64: + case BTF_KIND_DATASEC: + case BTF_KIND_FLOAT: + size = t->size; +@@ -644,6 +655,7 @@ int btf__align_of(const struct btf *btf, __u32 id) + switch (kind) { + case BTF_KIND_INT: + case BTF_KIND_ENUM: ++ case BTF_KIND_ENUM64: + case BTF_KIND_FLOAT: + return min(btf_ptr_sz(btf), (size_t)t->size); + case BTF_KIND_PTR: +@@ -2162,6 +2174,10 @@ static int btf_add_enum_common(struct btf *btf, const char *name, __u32 byte_sz, + */ + int btf__add_enum(struct btf *btf, const char *name, __u32 byte_sz) + { ++ /* ++ * set the signedness to be unsigned, it will change to signed ++ * if any later enumerator is negative. ++ */ + return btf_add_enum_common(btf, name, byte_sz, false, BTF_KIND_ENUM); + } + +@@ -2212,6 +2228,82 @@ int btf__add_enum_value(struct btf *btf, const char *name, __s64 value) + t = btf_last_type(btf); + btf_type_inc_vlen(t); + ++ /* if negative value, set signedness to signed */ ++ if (value < 0) ++ t->info = btf_type_info(btf_kind(t), btf_vlen(t), true); ++ ++ btf->hdr->type_len += sz; ++ btf->hdr->str_off += sz; ++ return 0; ++} ++ ++/* ++ * Append new BTF_KIND_ENUM64 type with: ++ * - *name* - name of the enum, can be NULL or empty for anonymous enums; ++ * - *byte_sz* - size of the enum, in bytes. ++ * - *is_signed* - whether the enum values are signed or not; ++ * ++ * Enum initially has no enum values in it (and corresponds to enum forward ++ * declaration). Enumerator values can be added by btf__add_enum64_value() ++ * immediately after btf__add_enum64() succeeds. ++ * ++ * Returns: ++ * - >0, type ID of newly added BTF type; ++ * - <0, on error. ++ */ ++int btf__add_enum64(struct btf *btf, const char *name, __u32 byte_sz, ++ bool is_signed) ++{ ++ return btf_add_enum_common(btf, name, byte_sz, is_signed, ++ BTF_KIND_ENUM64); ++} ++ ++/* ++ * Append new enum value for the current ENUM64 type with: ++ * - *name* - name of the enumerator value, can't be NULL or empty; ++ * - *value* - integer value corresponding to enum value *name*; ++ * Returns: ++ * - 0, on success; ++ * - <0, on error. ++ */ ++int btf__add_enum64_value(struct btf *btf, const char *name, __u64 value) ++{ ++ struct btf_enum64 *v; ++ struct btf_type *t; ++ int sz, name_off; ++ ++ /* last type should be BTF_KIND_ENUM64 */ ++ if (btf->nr_types == 0) ++ return libbpf_err(-EINVAL); ++ t = btf_last_type(btf); ++ if (!btf_is_enum64(t)) ++ return libbpf_err(-EINVAL); ++ ++ /* non-empty name */ ++ if (!name || !name[0]) ++ return libbpf_err(-EINVAL); ++ ++ /* decompose and invalidate raw data */ ++ if (btf_ensure_modifiable(btf)) ++ return libbpf_err(-ENOMEM); ++ ++ sz = sizeof(struct btf_enum64); ++ v = btf_add_type_mem(btf, sz); ++ if (!v) ++ return libbpf_err(-ENOMEM); ++ ++ name_off = btf__add_str(btf, name); ++ if (name_off < 0) ++ return name_off; ++ ++ v->name_off = name_off; ++ v->val_lo32 = (__u32)value; ++ v->val_hi32 = value >> 32; ++ ++ /* update parent type's vlen */ ++ t = btf_last_type(btf); ++ btf_type_inc_vlen(t); ++ + btf->hdr->type_len += sz; + btf->hdr->str_off += sz; + return 0; +@@ -4720,6 +4812,7 @@ int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ct + case BTF_KIND_INT: + case BTF_KIND_FLOAT: + case BTF_KIND_ENUM: ++ case BTF_KIND_ENUM64: + return 0; + + case BTF_KIND_FWD: +@@ -4814,6 +4907,16 @@ int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ct + } + break; + } ++ case BTF_KIND_ENUM64: { ++ struct btf_enum64 *m = btf_enum64(t); ++ ++ for (i = 0, n = btf_vlen(t); i < n; i++, m++) { ++ err = visit(&m->name_off, ctx); ++ if (err) ++ return err; ++ } ++ break; ++ } + case BTF_KIND_FUNC_PROTO: { + struct btf_param *m = btf_params(t); + +diff --git a/src/btf.h b/src/btf.h +index bddc4b3..2dc963c 100644 +--- a/src/btf.h ++++ b/src/btf.h +@@ -215,6 +215,8 @@ LIBBPF_API int btf__add_field(struct btf *btf, const char *name, int field_type_ + /* enum construction APIs */ + LIBBPF_API int btf__add_enum(struct btf *btf, const char *name, __u32 bytes_sz); + LIBBPF_API int btf__add_enum_value(struct btf *btf, const char *name, __s64 value); ++LIBBPF_API int btf__add_enum64(struct btf *btf, const char *name, __u32 bytes_sz, bool is_signed); ++LIBBPF_API int btf__add_enum64_value(struct btf *btf, const char *name, __u64 value); + + enum btf_fwd_kind { + BTF_FWD_STRUCT = 0, +@@ -455,6 +457,11 @@ static inline bool btf_is_enum(const struct btf_type *t) + return btf_kind(t) == BTF_KIND_ENUM; + } + ++static inline bool btf_is_enum64(const struct btf_type *t) ++{ ++ return btf_kind(t) == BTF_KIND_ENUM64; ++} ++ + static inline bool btf_is_fwd(const struct btf_type *t) + { + return btf_kind(t) == BTF_KIND_FWD; +@@ -555,6 +562,11 @@ static inline struct btf_member *btf_members(const struct btf_type *t) + return (struct btf_member *)(t + 1); + } + ++static inline struct btf_enum64 *btf_enum64(const struct btf_type *t) ++{ ++ return (struct btf_enum64 *)(t + 1); ++} ++ + /* Get bit offset of a member with specified index. */ + static inline __u32 btf_member_bit_offset(const struct btf_type *t, + __u32 member_idx) +diff --git a/src/libbpf.map b/src/libbpf.map +index c2df7aa..3f44c1d 100644 +--- a/src/libbpf.map ++++ b/src/libbpf.map +@@ -423,6 +423,8 @@ LIBBPF_0.6.0 { + + LIBBPF_0.7.0 { + global: ++ btf__add_enum64; ++ btf__add_enum64_value; + bpf_btf_load; + bpf_program__expected_attach_type; + bpf_program__log_buf; +-- +2.40.0 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 @@ +From a945df2439020ca182513b6e2f24175cbf2a2dc4 Mon Sep 17 00:00:00 2001 +From: Yonghong Song +Date: Mon, 6 Jun 2022 23:26:36 -0700 +Subject: [PATCH] libbpf: Add enum64 sanitization + +When old kernel does not support enum64 but user space btf +contains non-zero enum kflag or enum64, libbpf needs to +do proper sanitization so modified btf can be accepted +by the kernel. + +Sanitization for enum kflag can be achieved by clearing +the kflag bit. For enum64, the type is replaced with an +union of integer member types and the integer member size +must be smaller than enum64 size. If such an integer +type cannot be found, a new type is created and used +for union members. + +Acked-by: Andrii Nakryiko +Signed-off-by: Yonghong Song +Link: https://lore.kernel.org/r/20220607062636.3721375-1-yhs@fb.com +Signed-off-by: Alexei Starovoitov + +Upstream-Status: Backport [https://github.com/libbpf/libbpf/commit/a945df2439020ca182513b6e2f24175cbf2a2dc4] + +Signed-off-by: Soumya Sambu +--- + src/btf.h | 3 ++- + src/libbpf.c | 56 +++++++++++++++++++++++++++++++++++++++---- + src/libbpf_internal.h | 2 ++ + 3 files changed, 56 insertions(+), 5 deletions(-) + +diff --git a/src/btf.h b/src/btf.h +index 951ac74..bddc4b3 100644 +--- a/src/btf.h ++++ b/src/btf.h +@@ -393,9 +393,10 @@ btf_dump__dump_type_data(struct btf_dump *d, __u32 id, + #ifndef BTF_KIND_FLOAT + #define BTF_KIND_FLOAT 16 /* Floating point */ + #endif +-/* The kernel header switched to enums, so these two were never #defined */ ++/* The kernel header switched to enums, so the following were never #defined */ + #define BTF_KIND_DECL_TAG 17 /* Decl Tag */ + #define BTF_KIND_TYPE_TAG 18 /* Type Tag */ ++#define BTF_KIND_ENUM64 19 /* Enum for up-to 64bit values */ + + static inline __u16 btf_kind(const struct btf_type *t) + { +diff --git a/src/libbpf.c b/src/libbpf.c +index 2262bcd..5321025 100644 +--- a/src/libbpf.c ++++ b/src/libbpf.c +@@ -2110,6 +2110,7 @@ static const char *__btf_kind_str(__u16 kind) + case BTF_KIND_FLOAT: return "float"; + case BTF_KIND_DECL_TAG: return "decl_tag"; + case BTF_KIND_TYPE_TAG: return "type_tag"; ++ case BTF_KIND_ENUM64: return "enum64"; + default: return "unknown"; + } + } +@@ -2634,12 +2635,13 @@ static bool btf_needs_sanitization(struct bpf_object *obj) + bool has_func = kernel_supports(obj, FEAT_BTF_FUNC); + bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG); + bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG); ++ bool has_enum64 = kernel_supports(obj, FEAT_BTF_ENUM64); + + return !has_func || !has_datasec || !has_func_global || !has_float || +- !has_decl_tag || !has_type_tag; ++ !has_decl_tag || !has_type_tag || !has_enum64; + } + +-static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf) ++static int bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf) + { + bool has_func_global = kernel_supports(obj, FEAT_BTF_GLOBAL_FUNC); + bool has_datasec = kernel_supports(obj, FEAT_BTF_DATASEC); +@@ -2647,6 +2649,8 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf) + bool has_func = kernel_supports(obj, FEAT_BTF_FUNC); + bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG); + bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG); ++ bool has_enum64 = kernel_supports(obj, FEAT_BTF_ENUM64); ++ __u32 enum64_placeholder_id = 0; + struct btf_type *t; + int i, j, vlen; + +@@ -2709,8 +2713,32 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf) + /* replace TYPE_TAG with a CONST */ + t->name_off = 0; + t->info = BTF_INFO_ENC(BTF_KIND_CONST, 0, 0); +- } ++ } else if (!has_enum64 && btf_is_enum(t)) { ++ /* clear the kflag */ ++ t->info = btf_type_info(btf_kind(t), btf_vlen(t), false); ++ } else if (!has_enum64 && btf_is_enum64(t)) { ++ /* replace ENUM64 with a union */ ++ struct btf_member *m; ++ ++ if (enum64_placeholder_id == 0) { ++ enum64_placeholder_id = btf__add_int(btf, "enum64_placeholder", 1, 0); ++ if (enum64_placeholder_id < 0) ++ return enum64_placeholder_id; ++ ++ t = (struct btf_type *)btf__type_by_id(btf, i); ++ } ++ ++ m = btf_members(t); ++ vlen = btf_vlen(t); ++ t->info = BTF_INFO_ENC(BTF_KIND_UNION, 0, vlen); ++ for (j = 0; j < vlen; j++, m++) { ++ m->type = enum64_placeholder_id; ++ m->offset = 0; ++ } ++ } + } ++ ++ return 0; + } + + static bool libbpf_needs_btf(const struct bpf_object *obj) +@@ -3008,7 +3036,9 @@ static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj) + + /* enforce 8-byte pointers for BPF-targeted BTFs */ + btf__set_pointer_size(obj->btf, 8); +- bpf_object__sanitize_btf(obj, kern_btf); ++ err = bpf_object__sanitize_btf(obj, kern_btf); ++ if (err) ++ return err; + } + + if (obj->gen_loader) { +@@ -3515,6 +3545,10 @@ static enum kcfg_type find_kcfg_type(const struct btf *btf, int id, + if (strcmp(name, "libbpf_tristate")) + return KCFG_UNKNOWN; + return KCFG_TRISTATE; ++ case BTF_KIND_ENUM64: ++ if (strcmp(name, "libbpf_tristate")) ++ return KCFG_UNKNOWN; ++ return KCFG_TRISTATE; + case BTF_KIND_ARRAY: + if (btf_array(t)->nelems == 0) + return KCFG_UNKNOWN; +@@ -4662,6 +4696,17 @@ static int probe_perf_link(void) + return link_fd < 0 && err == -EBADF; + } + ++static int probe_kern_btf_enum64(void) ++{ ++ static const char strs[] = "\0enum64"; ++ __u32 types[] = { ++ BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8), ++ }; ++ ++ return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), ++ strs, sizeof(strs))); ++} ++ + enum kern_feature_result { + FEAT_UNKNOWN = 0, + FEAT_SUPPORTED = 1, +@@ -4724,6 +4769,9 @@ static struct kern_feature_desc { + [FEAT_MEMCG_ACCOUNT] = { + "memcg-based memory accounting", probe_memcg_account, + }, ++ [FEAT_BTF_ENUM64] = { ++ "BTF_KIND_ENUM64 support", probe_kern_btf_enum64, ++ }, + }; + + bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id) +diff --git a/src/libbpf_internal.h b/src/libbpf_internal.h +index bc86b82..2b72531 100644 +--- a/src/libbpf_internal.h ++++ b/src/libbpf_internal.h +@@ -329,6 +329,8 @@ enum kern_feature_id { + FEAT_BTF_TYPE_TAG, + /* memcg-based accounting for BPF maps and progs */ + FEAT_MEMCG_ACCOUNT, ++ /* BTF_KIND_ENUM64 support and BTF_KIND_ENUM kflag support */ ++ FEAT_BTF_ENUM64, + __FEAT_CNT, + }; + +-- +2.40.0 diff --git a/recipes-kernel/libbpf/libbpf/0001-libbpf-Refactor-btf__add_enum-for-future-code-sharin.patch b/recipes-kernel/libbpf/libbpf/0001-libbpf-Refactor-btf__add_enum-for-future-code-sharin.patch new file mode 100644 index 0000000..8bb1787 --- /dev/null +++ b/recipes-kernel/libbpf/libbpf/0001-libbpf-Refactor-btf__add_enum-for-future-code-sharin.patch @@ -0,0 +1,83 @@ +From 25fd7a1cf58f79db2bd84c6a9de9457107f1ed21 Mon Sep 17 00:00:00 2001 +From: Yonghong Song +Date: Mon, 6 Jun 2022 23:26:15 -0700 +Subject: [PATCH] libbpf: Refactor btf__add_enum() for future code sharing + +Refactor btf__add_enum() function to create a separate +function btf_add_enum_common() so later the common function +can be used to add enum64 btf type. There is no functionality +change for this patch. + +Acked-by: Andrii Nakryiko +Signed-off-by: Yonghong Song +Link: https://lore.kernel.org/r/20220607062615.3718063-1-yhs@fb.com +Signed-off-by: Alexei Starovoitov + +Upstream-Status: Backport [https://github.com/libbpf/libbpf/commit/25fd7a1cf58f79db2bd84c6a9de9457107f1ed21] + +Signed-off-by: Soumya Sambu +--- + src/btf.c | 36 +++++++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 15 deletions(-) + +diff --git a/src/btf.c b/src/btf.c +index 1383e26..5e0bf3c 100644 +--- a/src/btf.c ++++ b/src/btf.c +@@ -2115,20 +2115,8 @@ int btf__add_field(struct btf *btf, const char *name, int type_id, + return 0; + } + +-/* +- * Append new BTF_KIND_ENUM type with: +- * - *name* - name of the enum, can be NULL or empty for anonymous enums; +- * - *byte_sz* - size of the enum, in bytes. +- * +- * Enum initially has no enum values in it (and corresponds to enum forward +- * declaration). Enumerator values can be added by btf__add_enum_value() +- * immediately after btf__add_enum() succeeds. +- * +- * Returns: +- * - >0, type ID of newly added BTF type; +- * - <0, on error. +- */ +-int btf__add_enum(struct btf *btf, const char *name, __u32 byte_sz) ++static int btf_add_enum_common(struct btf *btf, const char *name, __u32 byte_sz, ++ bool is_signed, __u8 kind) + { + struct btf_type *t; + int sz, name_off = 0; +@@ -2153,12 +2141,30 @@ int btf__add_enum(struct btf *btf, const char *name, __u32 byte_sz) + + /* start out with vlen=0; it will be adjusted when adding enum values */ + t->name_off = name_off; +- t->info = btf_type_info(BTF_KIND_ENUM, 0, 0); ++ t->info = btf_type_info(kind, 0, is_signed); + t->size = byte_sz; + + return btf_commit_type(btf, sz); + } + ++/* ++ * Append new BTF_KIND_ENUM type with: ++ * - *name* - name of the enum, can be NULL or empty for anonymous enums; ++ * - *byte_sz* - size of the enum, in bytes. ++ * ++ * Enum initially has no enum values in it (and corresponds to enum forward ++ * declaration). Enumerator values can be added by btf__add_enum_value() ++ * immediately after btf__add_enum() succeeds. ++ * ++ * Returns: ++ * - >0, type ID of newly added BTF type; ++ * - <0, on error. ++ */ ++int btf__add_enum(struct btf *btf, const char *name, __u32 byte_sz) ++{ ++ return btf_add_enum_common(btf, name, byte_sz, false, BTF_KIND_ENUM); ++} ++ + /* + * Append new enum value for the current ENUM type with: + * - *name* - name of the enumerator value, can't be NULL or empty; +-- +2.40.0 diff --git a/recipes-kernel/libbpf/libbpf_%.bbappend b/recipes-kernel/libbpf/libbpf_%.bbappend index b5a6319..2a17de5 100644 --- a/recipes-kernel/libbpf/libbpf_%.bbappend +++ b/recipes-kernel/libbpf/libbpf_%.bbappend @@ -3,7 +3,14 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/libbpf:" LIC_FILES_CHKSUM = "file://LICENSE.LGPL-2.1;md5=b370887980db5dd40659b50909238dbd" SRC_URI += "\ - file://0001-libbpf-Introduce-bpf_-btf-link-map-prog-_get_info_by.patch" + file://0001-libbpf-Introduce-bpf_-btf-link-map-prog-_get_info_by.patch \ + file://0001-bpf-Add-multi-kprobe-link.patch \ + file://0001-libbpf-Add-bpf_link_create-support-for-multi-kprobes.patch \ + file://0001-bpf-Add-btf-enum64-support.patch \ + file://0001-bpf-Add-cookie-support-to-programs-attached-with-kpr.patch \ + file://0001-libbpf-Add-enum64-sanitization.patch \ + file://0001-libbpf-Refactor-btf__add_enum-for-future-code-sharin.patch \ + file://0001-libbpf-Add-enum64-parsing-and-new-enum64-public-API.patch" S = "${WORKDIR}/git" -- cgit v1.2.3-54-g00ecf