Skip to content

Commit eafcaa1

Browse files
AsphalttKernel Patches Daemon
authored andcommitted
bpf: Allow union argument in trampoline based programs
Currently, functions with 'union' arguments cannot be traced with fentry/fexit: bpftrace -e 'fentry:release_pages { exit(); }' -v AST node count: 6 Attaching 1 probe... ERROR: Error loading BPF program for fentry_vmlinux_release_pages_1. Kernel error log: The function release_pages arg0 type UNION is unsupported. processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0 ERROR: Loading BPF object(s) failed. The type of the 'release_pages' argument is defined as: typedef union { struct page **pages; struct folio **folios; struct encoded_page **encoded_pages; } release_pages_arg __attribute__ ((__transparent_union__)); This patch relaxes the restriction by allowing function arguments of type 'union' to be traced in verifier. Signed-off-by: Leon Hwang <[email protected]> Reviewed-by: Amery Hung <[email protected]>
1 parent 2b3c471 commit eafcaa1

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

include/linux/bpf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,9 @@ struct bpf_prog_offload {
11191119
/* The argument is signed. */
11201120
#define BTF_FMODEL_SIGNED_ARG BIT(1)
11211121

1122+
/* The argument is a union. */
1123+
#define BTF_FMODEL_UNION_ARG BIT(2)
1124+
11221125
struct btf_func_model {
11231126
u8 ret_size;
11241127
u8 ret_flags;

include/linux/btf.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,11 @@ static inline bool btf_type_is_struct(const struct btf_type *t)
404404
return kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION;
405405
}
406406

407+
static inline bool __btf_type_is_union(const struct btf_type *t)
408+
{
409+
return BTF_INFO_KIND(t->info) == BTF_KIND_UNION;
410+
}
411+
407412
static inline bool __btf_type_is_struct(const struct btf_type *t)
408413
{
409414
return BTF_INFO_KIND(t->info) == BTF_KIND_STRUCT;

kernel/bpf/btf.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6762,7 +6762,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
67626762
/* skip modifiers */
67636763
while (btf_type_is_modifier(t))
67646764
t = btf_type_by_id(btf, t->type);
6765-
if (btf_type_is_small_int(t) || btf_is_any_enum(t) || __btf_type_is_struct(t))
6765+
if (btf_type_is_small_int(t) || btf_is_any_enum(t) || btf_type_is_struct(t))
67666766
/* accessing a scalar */
67676767
return true;
67686768
if (!btf_type_is_ptr(t)) {
@@ -7334,7 +7334,7 @@ static int __get_type_size(struct btf *btf, u32 btf_id,
73347334
if (btf_type_is_ptr(t))
73357335
/* kernel size of pointer. Not BPF's size of pointer*/
73367336
return sizeof(void *);
7337-
if (btf_type_is_int(t) || btf_is_any_enum(t) || __btf_type_is_struct(t))
7337+
if (btf_type_is_int(t) || btf_is_any_enum(t) || btf_type_is_struct(t))
73387338
return t->size;
73397339
return -EINVAL;
73407340
}
@@ -7347,6 +7347,8 @@ static u8 __get_type_fmodel_flags(const struct btf_type *t)
73477347
flags |= BTF_FMODEL_STRUCT_ARG;
73487348
if (btf_type_is_signed_int(t))
73497349
flags |= BTF_FMODEL_SIGNED_ARG;
7350+
if (__btf_type_is_union(t))
7351+
flags |= BTF_FMODEL_UNION_ARG;
73507352

73517353
return flags;
73527354
}
@@ -7384,7 +7386,7 @@ int btf_distill_func_proto(struct bpf_verifier_log *log,
73847386
return -EINVAL;
73857387
}
73867388
ret = __get_type_size(btf, func->type, &t);
7387-
if (ret < 0 || __btf_type_is_struct(t)) {
7389+
if (ret < 0 || btf_type_is_struct(t)) {
73887390
bpf_log(log,
73897391
"The function %s return type %s is unsupported.\n",
73907392
tname, btf_type_str(t));

0 commit comments

Comments
 (0)