Skip to content

Commit 73f0958

Browse files
seehearfeelAirFortressIlikara
authored andcommitted
LoongArch: BPF: Add struct ops support for trampoline
Use BPF_TRAMP_F_INDIRECT flag to detect struct ops and emit proper prologue and epilogue for this case. With this patch, all of the struct_ops related testcases (except struct_ops_multi_pages) passed on LoongArch. The testcase struct_ops_multi_pages failed is because the actual image_pages_cnt is 40 which is bigger than MAX_TRAMP_IMAGE_PAGES. Before: $ sudo ./test_progs -t struct_ops -d struct_ops_multi_pages ... WATCHDOG: test case struct_ops_module/struct_ops_load executes for 10 seconds... After: $ sudo ./test_progs -t struct_ops -d struct_ops_multi_pages ... #15 bad_struct_ops:OK ... torvalds#399 struct_ops_autocreate:OK ... torvalds#400 struct_ops_kptr_return:OK ... torvalds#401 struct_ops_maybe_null:OK ... torvalds#402 struct_ops_module:OK ... torvalds#404 struct_ops_no_cfi:OK ... torvalds#405 struct_ops_private_stack:SKIP ... torvalds#406 struct_ops_refcounted:OK Summary: 8/25 PASSED, 3 SKIPPED, 0 FAILED Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: maoxiaochuan <maoxiaochuan@loongson.cn>
1 parent 4fe77e9 commit 73f0958

File tree

1 file changed

+50
-25
lines changed

1 file changed

+50
-25
lines changed

arch/loongarch/net/bpf_jit.c

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
14131413
int i, ret, save_ret;
14141414
int stack_size = 0, nargs = 0;
14151415
int retval_off, args_off, nargs_off, ip_off, run_ctx_off, sreg_off;
1416+
bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT;
14161417
void *orig_call = func_addr;
14171418
struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
14181419
struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT];
@@ -1490,18 +1491,33 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
14901491

14911492
stack_size = round_up(stack_size, 16);
14921493

1493-
/* For the trampoline called from function entry */
1494-
/* RA and FP for parent function */
1495-
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -16);
1496-
emit_insn(ctx, std, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, 8);
1497-
emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0);
1498-
emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 16);
1499-
1500-
/* RA and FP for traced function */
1501-
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -stack_size);
1502-
emit_insn(ctx, std, LOONGARCH_GPR_T0, LOONGARCH_GPR_SP, stack_size - 8);
1503-
emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16);
1504-
emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size);
1494+
if (is_struct_ops) {
1495+
/*
1496+
* For the trampoline called directly, just handle
1497+
* the frame of trampoline.
1498+
*/
1499+
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -stack_size);
1500+
emit_insn(ctx, std, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, stack_size - 8);
1501+
emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16);
1502+
emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size);
1503+
} else {
1504+
/*
1505+
* For the trampoline called from function entry,
1506+
* the frame of traced function and the frame of
1507+
* trampoline need to be considered.
1508+
*/
1509+
/* RA and FP for parent function */
1510+
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -16);
1511+
emit_insn(ctx, std, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, 8);
1512+
emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0);
1513+
emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 16);
1514+
1515+
/* RA and FP for traced function */
1516+
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -stack_size);
1517+
emit_insn(ctx, std, LOONGARCH_GPR_T0, LOONGARCH_GPR_SP, stack_size - 8);
1518+
emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16);
1519+
emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size);
1520+
}
15051521

15061522
/* callee saved register S1 to pass start time */
15071523
emit_insn(ctx, std, LOONGARCH_GPR_S1, LOONGARCH_GPR_FP, -sreg_off);
@@ -1589,21 +1605,30 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
15891605

15901606
emit_insn(ctx, ldd, LOONGARCH_GPR_S1, LOONGARCH_GPR_FP, -sreg_off);
15911607

1592-
/* trampoline called from function entry */
1593-
emit_insn(ctx, ldd, LOONGARCH_GPR_T0, LOONGARCH_GPR_SP, stack_size - 8);
1594-
emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16);
1595-
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, stack_size);
1596-
1597-
emit_insn(ctx, ldd, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, 8);
1598-
emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0);
1599-
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, 16);
1608+
if (is_struct_ops) {
1609+
/* trampoline called directly */
1610+
emit_insn(ctx, ldd, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, stack_size - 8);
1611+
emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16);
1612+
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, stack_size);
16001613

1601-
if (flags & BPF_TRAMP_F_SKIP_FRAME)
1602-
/* return to parent function */
16031614
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0);
1604-
else
1605-
/* return to traced function */
1606-
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T0, 0);
1615+
} else {
1616+
/* trampoline called from function entry */
1617+
emit_insn(ctx, ldd, LOONGARCH_GPR_T0, LOONGARCH_GPR_SP, stack_size - 8);
1618+
emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16);
1619+
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, stack_size);
1620+
1621+
emit_insn(ctx, ldd, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, 8);
1622+
emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0);
1623+
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, 16);
1624+
1625+
if (flags & BPF_TRAMP_F_SKIP_FRAME)
1626+
/* return to parent function */
1627+
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0);
1628+
else
1629+
/* return to traced function */
1630+
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T0, 0);
1631+
}
16071632

16081633
ret = ctx->idx;
16091634
out:

0 commit comments

Comments
 (0)