@@ -1106,6 +1106,7 @@ struct btf_func_model {
u8 nr_args;
u8 arg_size[MAX_BPF_FUNC_ARGS];
u8 arg_flags[MAX_BPF_FUNC_ARGS];
+ u8 arg_largest_member_size[MAX_BPF_FUNC_ARGS];
};
/* Restore arguments before returning from trampoline to let original function
@@ -7318,6 +7318,29 @@ static int __get_type_size(struct btf *btf, u32 btf_id,
return -EINVAL;
}
+static u8 __get_largest_member_size(struct btf *btf, const struct btf_type *t)
+{
+ const struct btf_member *member;
+ const struct btf_type *mtype;
+ u8 largest_member_size = 0;
+ int i;
+
+ if (!__btf_type_is_struct(t))
+ return largest_member_size;
+
+ for_each_member(i, t, member) {
+ mtype = btf_type_by_id(btf, member->type);
+ while (mtype && btf_type_is_modifier(mtype))
+ mtype = btf_type_by_id(btf, mtype->type);
+ if (!mtype)
+ return -EINVAL;
+ if (mtype->size > largest_member_size)
+ largest_member_size = mtype->size;
+ }
+
+ return largest_member_size;
+}
+
static u8 __get_type_fmodel_flags(const struct btf_type *t)
{
u8 flags = 0;
@@ -7396,6 +7419,8 @@ int btf_distill_func_proto(struct bpf_verifier_log *log,
}
m->arg_size[i] = ret;
m->arg_flags[i] = __get_type_fmodel_flags(t);
+ m->arg_largest_member_size[i] =
+ __get_largest_member_size(btf, t);
}
m->nr_args = nargs;
return 0;
In order to properly JIT the trampolines needed to attach BPF programs to functions, some architectures like ARM64 need to know about the alignment needed for the function arguments. Such alignment can generally be deduced from the argument size, but that's not completely true for composite types. In the specific case of ARM64, the AAPCS64 ABI defines that a composite type which needs to be passed through stack must be aligned on the maximum between 8 and the largest alignment constraint of its first-level members. So the JIT compiler needs more information about the arguments to make sure to generate code that respects those alignment constraints. For struct arguments, add information about the size of the largest first-level member in the struct btf_func_model to allow the JIT compiler to guess the needed alignment. The information is quite specific, but it allows to keep arch-specific concerns (ie: guessing the final needed alignment for an argument) isolated in each JIT compiler. Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com> --- include/linux/bpf.h | 1 + kernel/bpf/btf.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+)