]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bpf: Allow union argument in trampoline based programs
authorLeon Hwang <leon.hwang@linux.dev>
Fri, 19 Sep 2025 04:41:09 +0000 (12:41 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 23 Sep 2025 19:07:46 +0000 (12:07 -0700)
Currently, functions with 'union' arguments cannot be traced with
fentry/fexit:

bpftrace -e 'fentry:release_pages { exit(); }' -v

The function release_pages arg0 type UNION is unsupported.

The type of the 'release_pages' arg0 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.

Reviewed-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
Link: https://lore.kernel.org/r/20250919044110.23729-2-leon.hwang@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/linux/bpf.h
kernel/bpf/btf.c

index a2ab51fa8b0ab90e47f81c76ae6c9a5a35d644cb..ba3a3be7eb2a8a7ff587e9aa54275d0f7a09cc4c 100644 (file)
@@ -1128,7 +1128,7 @@ struct bpf_prog_offload {
  */
 #define MAX_BPF_FUNC_REG_ARGS 5
 
-/* The argument is a structure. */
+/* The argument is a structure or a union. */
 #define BTF_FMODEL_STRUCT_ARG          BIT(0)
 
 /* The argument is signed. */
index 9f47a3aa7ff8997247e59f3d6474434845db29a3..0de8fc8a0e0b32239ede752c8a18de5018ef168f 100644 (file)
@@ -6751,7 +6751,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
        /* skip modifiers */
        while (btf_type_is_modifier(t))
                t = btf_type_by_id(btf, t->type);
-       if (btf_type_is_small_int(t) || btf_is_any_enum(t) || __btf_type_is_struct(t))
+       if (btf_type_is_small_int(t) || btf_is_any_enum(t) || btf_type_is_struct(t))
                /* accessing a scalar */
                return true;
        if (!btf_type_is_ptr(t)) {
@@ -7323,7 +7323,7 @@ static int __get_type_size(struct btf *btf, u32 btf_id,
        if (btf_type_is_ptr(t))
                /* kernel size of pointer. Not BPF's size of pointer*/
                return sizeof(void *);
-       if (btf_type_is_int(t) || btf_is_any_enum(t) || __btf_type_is_struct(t))
+       if (btf_type_is_int(t) || btf_is_any_enum(t) || btf_type_is_struct(t))
                return t->size;
        return -EINVAL;
 }
@@ -7332,7 +7332,7 @@ static u8 __get_type_fmodel_flags(const struct btf_type *t)
 {
        u8 flags = 0;
 
-       if (__btf_type_is_struct(t))
+       if (btf_type_is_struct(t))
                flags |= BTF_FMODEL_STRUCT_ARG;
        if (btf_type_is_signed_int(t))
                flags |= BTF_FMODEL_SIGNED_ARG;
@@ -7373,7 +7373,7 @@ int btf_distill_func_proto(struct bpf_verifier_log *log,
                return -EINVAL;
        }
        ret = __get_type_size(btf, func->type, &t);
-       if (ret < 0 || __btf_type_is_struct(t)) {
+       if (ret < 0 || btf_type_is_struct(t)) {
                bpf_log(log,
                        "The function %s return type %s is unsupported.\n",
                        tname, btf_type_str(t));