[PATCH bpf-next v1 07/14] bpf, loongarch: Fix stack arguments for indirect trampolines
Kumar Kartikeya Dwivedi <[email protected]>
| Newsgroups | org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
LoongArch passes arguments beyond a0-a7 at the caller stack pointer. The
trampoline store_args() helper always reads those arguments at FP + 16,
which is correct for an fentry trampoline: its prologue leaves FP 16 bytes
below the stack pointer at trampoline entry after accounting for the saved
parent and traced-function frames.
A struct_ops indirect trampoline is entered through a function pointer and
only saves its own RA and FP before setting FP to the entry stack pointer.
Its stack arguments therefore start at FP, not FP + 16. As a result, every
stack-passed struct_ops argument is currently read two slots late.
Select the source offset based on whether the trampoline is indirect. This
also prepares the stack-passed arena argument path to consume the actual
pointer slot.
Fixes: c9ebe2016de9 ("LoongArch: BPF: Support up to 12 function arguments for trampoline")
Cc: Tiezhu Yang <[email protected]>
Cc: Huacai Chen <[email protected]>
Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]>
---
arch/loongarch/net/bpf_jit.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 29c281bef28e..d193293a0fd2 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -1662,17 +1662,18 @@ int bpf_arch_text_invalidate(void *dst, size_t len)
return ret;
}
-static void store_args(struct jit_ctx *ctx, int nr_arg_slots, int args_off)
+static void store_args(struct jit_ctx *ctx, int nr_arg_slots, int args_off, bool is_struct_ops)
{
+ int stack_args_off = is_struct_ops ? 0 : 16;
int i;
for (i = 0; i < nr_arg_slots; i++) {
if (i < LOONGARCH_MAX_REG_ARGS)
emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off);
else {
- /* Skip slots for T0 and FP of traced function */
+ /* Skip the saved T0 and FP slots for a traced function. */
emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP,
- 16 + (i - LOONGARCH_MAX_REG_ARGS) * 8);
+ stack_args_off + (i - LOONGARCH_MAX_REG_ARGS) * 8);
emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -args_off);
}
args_off -= 8;
@@ -1995,7 +1996,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
func_meta = nr_arg_slots;
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, func_meta);
- store_args(ctx, nr_arg_slots, args_off);
+ store_args(ctx, nr_arg_slots, args_off, is_struct_ops);
if (bpf_fsession_cnt(tnodes)) {
/* clear all session cookies' value */
--
2.53.0