@@ -108,6 +108,29 @@ static void test_struct_many_args(void)
ASSERT_EQ(skel->bss->t9_i, 27, "t9:i");
ASSERT_EQ(skel->bss->t9_ret, 258, "t9 ret");
+ ASSERT_EQ(skel->bss->t10_a_a, 27, "t10:a.a");
+ ASSERT_EQ(skel->bss->t10_a_b, 28, "t10:a.b");
+ ASSERT_EQ(skel->bss->t10_b_a, 29, "t10:b.a");
+ ASSERT_EQ(skel->bss->t10_b_b, 30, "t10:b.b");
+ ASSERT_EQ(skel->bss->t10_c_a, 31, "t10:c.a");
+ ASSERT_EQ(skel->bss->t10_c_b, 32, "t10:c.b");
+ ASSERT_EQ(skel->bss->t10_d_a, 33, "t10:d.a");
+ ASSERT_EQ(skel->bss->t10_d_b, 34, "t10:d.b");
+ ASSERT_EQ(skel->bss->t10_e, 35, "t10:e");
+ ASSERT_EQ(skel->bss->t10_f_a, 36, "t10:f.a");
+ ASSERT_EQ(skel->bss->t10_f_b, 37, "t10:f.b");
+
+ ASSERT_EQ(skel->bss->t10_ret, 352, "t10 ret");
+
+ ASSERT_EQ(skel->bss->t11_a, 38, "t11:a");
+ ASSERT_EQ(skel->bss->t11_b, 39, "t11:b");
+ ASSERT_EQ(skel->bss->t11_c, 40, "t11:c");
+ ASSERT_EQ(skel->bss->t11_d, 41, "t11:d");
+ ASSERT_EQ(skel->bss->t11_e, 42, "t11:e");
+ ASSERT_EQ(skel->bss->t11_f, 43, "t11:f");
+
+ ASSERT_EQ(skel->bss->t11_ret, 243, "t11 ret");
+
destroy_skel:
tracing_struct_many_args__destroy(skel);
}
@@ -18,6 +18,15 @@ struct bpf_testmod_struct_arg_3 {
int b[];
};
+struct bpf_testmod_struct_arg_4 {
+ __u64 a;
+ __u64 b;
+};
+
+struct bpf_testmod_struct_arg_5 {
+ __int128 a;
+};
+
long t1_a_a, t1_a_b, t1_b, t1_c, t1_ret, t1_nregs;
__u64 t1_reg0, t1_reg1, t1_reg2, t1_reg3;
long t2_a, t2_b_a, t2_b_b, t2_c, t2_ret;
@@ -25,7 +34,6 @@ long t3_a, t3_b, t3_c_a, t3_c_b, t3_ret;
long t4_a_a, t4_b, t4_c, t4_d, t4_e_a, t4_e_b, t4_ret;
long t5_ret;
int t6;
-
SEC("fentry/bpf_testmod_test_struct_arg_1")
int BPF_PROG2(test_struct_arg_1, struct bpf_testmod_struct_arg_2, a, int, b, int, c)
{
@@ -18,6 +18,14 @@ struct bpf_testmod_struct_arg_5 {
long t7_a, t7_b, t7_c, t7_d, t7_e, t7_f_a, t7_f_b, t7_ret;
long t8_a, t8_b, t8_c, t8_d, t8_e, t8_f_a, t8_f_b, t8_g, t8_ret;
long t9_a, t9_b, t9_c, t9_d, t9_e, t9_f, t9_g, t9_h_a, t9_h_b, t9_h_c, t9_h_d, t9_i, t9_ret;
+__u64 t10_a_a, t10_a_b, t10_b_a, t10_b_b, t10_c_a, t10_c_b, t10_d_a, t10_d_b,
+ t10_f_a, t10_f_b;
+short t10_e;
+int t10_ret;
+__int128 t11_a, t11_b, t11_c, t11_d, t11_f;
+short t11_e;
+int t11_ret;
+
SEC("fentry/bpf_testmod_test_struct_arg_7")
int BPF_PROG2(test_struct_many_args_1, __u64, a, void *, b, short, c, int, d,
@@ -92,4 +100,63 @@ int BPF_PROG2(test_struct_many_args_6, __u64, a, void *, b, short, c, int, d, vo
return 0;
}
+SEC("fentry/bpf_testmod_test_struct_arg_10")
+int BPF_PROG2(test_struct_many_args_7, struct bpf_testmod_struct_arg_4, a,
+ struct bpf_testmod_struct_arg_4, b,
+ struct bpf_testmod_struct_arg_4, c,
+ struct bpf_testmod_struct_arg_4, d, short, e,
+ struct bpf_testmod_struct_arg_4, f)
+{
+ t10_a_a = a.a;
+ t10_a_b = a.b;
+ t10_b_a = b.a;
+ t10_b_b = b.b;
+ t10_c_a = c.a;
+ t10_c_b = c.b;
+ t10_d_a = d.a;
+ t10_d_b = d.b;
+ t10_e = e;
+ t10_f_a = f.a;
+ t10_f_b = f.b;
+ return 0;
+}
+
+SEC("fexit/bpf_testmod_test_struct_arg_10")
+int BPF_PROG2(test_struct_many_args_8, struct bpf_testmod_struct_arg_4, a,
+ struct bpf_testmod_struct_arg_4, b,
+ struct bpf_testmod_struct_arg_4, c,
+ struct bpf_testmod_struct_arg_4, d, short, e,
+ struct bpf_testmod_struct_arg_4, f, int, ret)
+{
+ t10_ret = ret;
+ return 0;
+}
+
+SEC("fentry/bpf_testmod_test_struct_arg_11")
+int BPF_PROG2(test_struct_many_args_9, struct bpf_testmod_struct_arg_5, a,
+ struct bpf_testmod_struct_arg_5, b,
+ struct bpf_testmod_struct_arg_5, c,
+ struct bpf_testmod_struct_arg_5, d, int, e,
+ struct bpf_testmod_struct_arg_5, f)
+{
+ t11_a = a.a;
+ t11_b = b.a;
+ t11_c = c.a;
+ t11_d = d.a;
+ t11_e = e;
+ t11_f = f.a;
+ return 0;
+}
+
+SEC("fexit/bpf_testmod_test_struct_arg_11")
+int BPF_PROG2(test_struct_many_args_10, struct bpf_testmod_struct_arg_5, a,
+ struct bpf_testmod_struct_arg_5, b,
+ struct bpf_testmod_struct_arg_5, c,
+ struct bpf_testmod_struct_arg_5, d, int, e,
+ struct bpf_testmod_struct_arg_5, f, int, ret)
+{
+ t11_ret = ret;
+ return 0;
+}
+
char _license[] SEC("license") = "GPL";
@@ -62,6 +62,15 @@ struct bpf_testmod_struct_arg_5 {
long d;
};
+struct bpf_testmod_struct_arg_6 {
+ u64 a;
+ u64 b;
+};
+
+struct bpf_testmod_struct_arg_7 {
+ __int128 a;
+};
+
__bpf_hook_start();
noinline int
@@ -128,6 +137,29 @@ bpf_testmod_test_struct_arg_9(u64 a, void *b, short c, int d, void *e, char f,
return bpf_testmod_test_struct_arg_result;
}
+noinline int bpf_testmod_test_struct_arg_10(struct bpf_testmod_struct_arg_6 a,
+ struct bpf_testmod_struct_arg_6 b,
+ struct bpf_testmod_struct_arg_6 c,
+ struct bpf_testmod_struct_arg_6 d,
+ short e,
+ struct bpf_testmod_struct_arg_6 f)
+{
+ bpf_testmod_test_struct_arg_result =
+ a.a + a.b + b.a + b.b + c.a + c.b + d.a + d.b + e + f.a + f.b;
+ return bpf_testmod_test_struct_arg_result;
+}
+
+noinline int bpf_testmod_test_struct_arg_11(struct bpf_testmod_struct_arg_7 a,
+ struct bpf_testmod_struct_arg_7 b,
+ struct bpf_testmod_struct_arg_7 c,
+ struct bpf_testmod_struct_arg_7 d,
+ short e,
+ struct bpf_testmod_struct_arg_7 f)
+{
+ bpf_testmod_test_struct_arg_result = a.a + b.a + c.a + d.a + e + f.a;
+ return bpf_testmod_test_struct_arg_result;
+}
+
noinline int
bpf_testmod_test_arg_ptr_to_struct(struct bpf_testmod_struct_arg_1 *a) {
bpf_testmod_test_struct_arg_result = a->a;
@@ -394,6 +426,16 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
struct bpf_testmod_struct_arg_3 *struct_arg3;
struct bpf_testmod_struct_arg_4 struct_arg4 = {21, 22};
struct bpf_testmod_struct_arg_5 struct_arg5 = {23, 24, 25, 26};
+ struct bpf_testmod_struct_arg_6 struct_arg6_a = {27, 28};
+ struct bpf_testmod_struct_arg_6 struct_arg6_b = {29, 30};
+ struct bpf_testmod_struct_arg_6 struct_arg6_c = {31, 32};
+ struct bpf_testmod_struct_arg_6 struct_arg6_d = {33, 34};
+ struct bpf_testmod_struct_arg_6 struct_arg6_f = {36, 37};
+ struct bpf_testmod_struct_arg_7 struct_arg7_a = {38};
+ struct bpf_testmod_struct_arg_7 struct_arg7_b = {39};
+ struct bpf_testmod_struct_arg_7 struct_arg7_c = {40};
+ struct bpf_testmod_struct_arg_7 struct_arg7_d = {41};
+ struct bpf_testmod_struct_arg_7 struct_arg7_f = {43};
int i = 1;
while (bpf_testmod_return_ptr(i))
@@ -411,6 +453,14 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
(void)bpf_testmod_test_struct_arg_9(16, (void *)17, 18, 19, (void *)20,
21, 22, struct_arg5, 27);
+ (void)bpf_testmod_test_struct_arg_10(struct_arg6_a, struct_arg6_b,
+ struct_arg6_c, struct_arg6_d, 35,
+ struct_arg6_f);
+
+ (void)bpf_testmod_test_struct_arg_11(struct_arg7_a, struct_arg7_b,
+ struct_arg7_c, struct_arg7_d, 42,
+ struct_arg7_f);
+
(void)bpf_testmod_test_arg_ptr_to_struct(&struct_arg1_2);
(void)trace_bpf_testmod_test_raw_tp_null(NULL);
When dealing with large types (>8 bytes), ARM64 trampolines need to take extra care about the arguments alignment to respect the calling convention set by AAPCS64. Add two tests ensuring that the BPF trampoline arranges arguments with the relevant layout. The two new tests involve almost the same arguments, except that the second one requires a more specific alignment to be set by the trampoline when preparing arguments before calling the the target function. Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com> --- .../selftests/bpf/prog_tests/tracing_struct.c | 23 ++++++++ tools/testing/selftests/bpf/progs/tracing_struct.c | 10 +++- .../selftests/bpf/progs/tracing_struct_many_args.c | 67 ++++++++++++++++++++++ .../testing/selftests/bpf/test_kmods/bpf_testmod.c | 50 ++++++++++++++++ 4 files changed, 149 insertions(+), 1 deletion(-)