From nobody Fri Apr 17 03:01:37 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0D13B36405F; Tue, 24 Feb 2026 07:36:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771918599; cv=none; b=Eh2HH8eyGcQH7uLA2go5Z0IdSIYuDOazn84RRQRiqFOIxsfURHLFzH/UlKM09Uo0xU3HKHSaWuyANwJ3HwX527DgmYtZx5wxCM1kRrCHzWI1zT9W6+m5Wb13/ITwkA039BAyLW1w3aY+n+0SOagTddfzyaq4QJP8y7ycMpEwL0k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771918599; c=relaxed/simple; bh=YUwQpWAZ98BGv+KiycMPE2KKwDQUXb3+lbMpDSDyEKQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=a1x/wJ5NbeGWB9ePoeMvcThxnq1frR6iy5EUutSY1FwQUAWmRCqDK3c95/q9b8246XEyxtB8aRSYAY05efFy2XpKJ9Le38QbyCP6xI/c534mp8Ke/XYkNNbv5gIKUH5Vbj2Ou0fXjXGOXczbG2Jf0LhhlRSvB7DJQ4GYfY/8S9Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8BxWcK2VJ1p1KcUAA--.63630S3; Tue, 24 Feb 2026 15:35:18 +0800 (CST) Received: from linux.localdomain (unknown [113.200.148.30]) by front1 (Coremail) with SMTP id qMiowJDxD8O0VJ1p9kxKAA--.9173S3; Tue, 24 Feb 2026 15:35:17 +0800 (CST) From: Tiezhu Yang To: Huacai Chen , Hengqi Chen Cc: loongarch@lists.linux.dev, bpf@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 1/3] LoongArch: BPF: Open code and remove invoke_bpf_mod_ret() Date: Tue, 24 Feb 2026 15:35:13 +0800 Message-ID: <20260224073515.1273-2-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260224073515.1273-1-yangtiezhu@loongson.cn> References: <20260224073515.1273-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDxD8O0VJ1p9kxKAA--.9173S3 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoW7Aw18Kw15ZFWUWF15WF47KFX_yoW8ury7pr nrCrW8ArW0gr43XFZ7Xr4UXr1ayanIgry3WasrKrZ7ua13Zry5W34xG3sa9F90kr9YyFyx ZrsYy39F9F17GabCm3ZEXasCq-sJn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUkYb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r126r13M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0cIa020Ex4CE44I27w Aqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE 14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x 0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E 7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAIcV C0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr1lIxAIcVCF 04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7 CjxVAFwI0_Jr0_GrUvcSsGvfC2KfnxnUUI43ZEXa7IU8niSPUUUUU== Content-Type: text/plain; charset="utf-8" invoke_bpf_mod_ret() is a small wrapper over invoke_bpf_prog(), it should check the return value of invoke_bpf_prog() and then return immediately if invoke_bpf_prog() failed, just open code and remove it due to it is called only once. Signed-off-by: Tiezhu Yang Acked-by: Hengqi Chen Tested-by: Hengqi Chen --- arch/loongarch/net/bpf_jit.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index 3bd89f55960d..98c04d6056f4 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -1544,20 +1544,6 @@ static int invoke_bpf_prog(struct jit_ctx *ctx, stru= ct bpf_tramp_link *l, return ret; } =20 -static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_links= *tl, - int args_off, int retval_off, int run_ctx_off, u32 **branches) -{ - int i; - - emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off); - for (i =3D 0; i < tl->nr_links; i++) { - invoke_bpf_prog(ctx, tl->links[i], args_off, retval_off, run_ctx_off, tr= ue); - emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -retval_off); - branches[i] =3D (u32 *)ctx->image + ctx->idx; - emit_insn(ctx, nop); - } -} - void *arch_alloc_bpf_trampoline(unsigned int size) { return bpf_prog_pack_alloc(size, jit_fill_hole); @@ -1764,7 +1750,16 @@ static int __arch_prepare_bpf_trampoline(struct jit_= ctx *ctx, struct bpf_tramp_i if (!branches) return -ENOMEM; =20 - invoke_bpf_mod_ret(ctx, fmod_ret, args_off, retval_off, run_ctx_off, bra= nches); + emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off); + for (i =3D 0; i < fmod_ret->nr_links; i++) { + ret =3D invoke_bpf_prog(ctx, fmod_ret->links[i], args_off, retval_off, + run_ctx_off, true); + if (ret) + goto out; + emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -retval_off); + branches[i] =3D (u32 *)ctx->image + ctx->idx; + emit_insn(ctx, nop); + } } =20 if (flags & BPF_TRAMP_F_CALL_ORIG) { --=20 2.42.0 From nobody Fri Apr 17 03:01:37 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0D2DF3644BE; Tue, 24 Feb 2026 07:36:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771918599; cv=none; b=KHjfTaI6g+uhsedmo6aDFaqRzKTYer7+KKa5zfbGM4mI0pC50awXqa9PCPOUIqoM1EIv7LGOzZki5G9Im+e++xfPXoNbJMeXQIav31GP1lq1RVyvQJ/4iejjjlLOdWnyITbLXfz+xKoZi3gJmxEPXFL33SZQtamkfEyWil8fE5Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771918599; c=relaxed/simple; bh=iaacxNVDtXkpCqOoUsyH77L0rhFw34H652SiOL1g9FA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NrWAJqDFr2Q74Ltu/mEN/1WDtNwPvdvad8MboWRbsLcRqioxjBaMxMdslb+lAH/YRPFaWr7xYHgvdjrhy0HLy5dbFlapGdc+Pb4CHJWAFMDdjZFzlwRcPQAcgqaANqIz1B6Q/K4PaEh2zTb9PTVOyS6+0YastVz5NFjHKNbUzwg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8DxAfG3VJ1p2acUAA--.63601S3; Tue, 24 Feb 2026 15:35:19 +0800 (CST) Received: from linux.localdomain (unknown [113.200.148.30]) by front1 (Coremail) with SMTP id qMiowJDxD8O0VJ1p9kxKAA--.9173S4; Tue, 24 Feb 2026 15:35:18 +0800 (CST) From: Tiezhu Yang To: Huacai Chen , Hengqi Chen Cc: loongarch@lists.linux.dev, bpf@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 2/3] LoongArch: BPF: Support small struct arguments for trampoline Date: Tue, 24 Feb 2026 15:35:14 +0800 Message-ID: <20260224073515.1273-3-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260224073515.1273-1-yangtiezhu@loongson.cn> References: <20260224073515.1273-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDxD8O0VJ1p9kxKAA--.9173S4 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoW3WF45Xr4UCr15CFy7trykXrc_yoW7ZFyrpF 1qkwsxCF48JFW7WaykXr4UWFyYkFs3A3y3urWUG39aya15Xry5JF4rKFn0yFy5GrykAF1f ursYvryqkF1xJwcCm3ZEXasCq-sJn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUkFb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0cIa020Ex4CE44I27w Aqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_Jw0_WrylYx0Ex4A2jsIE 14v26r4j6F4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x 0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E 7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAIcV C0I7IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF 04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7 CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x07j8CztUUUUU= Content-Type: text/plain; charset="utf-8" In the current BPF code, the struct argument size is at most 16 bytes, enforced by the verifier. According to the Procedure Call Standard for LoongArch [1], the struct argument size below 16 bytes are provided as part of the 8 argument registers, that is to say, the struct argument may be passed in a pair of registers if its size is more than 8 bytes and no more than 16 bytes. Extend the BPF trampoline JIT to support attachment to functions that take small structures (up to 16 bytes) as argument, save and restore a number of "argument registers" rather than a number of arguments. With this patch, the following related testcases passed: sudo ./test_progs -a tracing_struct/struct_args sudo ./test_progs -a tracing_struct/union_args Link: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc#stru= ctures [1] Signed-off-by: Tiezhu Yang Acked-by: Hengqi Chen Tested-by: Hengqi Chen --- arch/loongarch/net/bpf_jit.c | 55 ++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index 98c04d6056f4..fef002bd3ffb 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -1460,21 +1460,21 @@ int bpf_arch_text_invalidate(void *dst, size_t len) return ret; } =20 -static void store_args(struct jit_ctx *ctx, int nargs, int args_off) +static void store_args(struct jit_ctx *ctx, int nregs, int args_off) { int i; =20 - for (i =3D 0; i < nargs; i++) { + for (i =3D 0; i < nregs; i++) { emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off); args_off -=3D 8; } } =20 -static void restore_args(struct jit_ctx *ctx, int nargs, int args_off) +static void restore_args(struct jit_ctx *ctx, int nregs, int args_off) { int i; =20 - for (i =3D 0; i < nargs; i++) { + for (i =3D 0; i < nregs; i++) { emit_insn(ctx, ldd, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off); args_off -=3D 8; } @@ -1590,8 +1590,8 @@ static int __arch_prepare_bpf_trampoline(struct jit_c= tx *ctx, struct bpf_tramp_i void *func_addr, u32 flags) { int i, ret, save_ret; - int stack_size, nargs; - int retval_off, args_off, nargs_off, ip_off, run_ctx_off, sreg_off, tcc_p= tr_off; + int stack_size, nregs =3D m->nr_args; + int retval_off, args_off, nregs_off, ip_off, run_ctx_off, sreg_off, tcc_p= tr_off; bool is_struct_ops =3D flags & BPF_TRAMP_F_INDIRECT; void *orig_call =3D func_addr; struct bpf_tramp_links *fentry =3D &tlinks[BPF_TRAMP_FENTRY]; @@ -1611,11 +1611,11 @@ static int __arch_prepare_bpf_trampoline(struct jit= _ctx *ctx, struct bpf_tramp_i * * FP - retval_off [ return value ] BPF_TRAMP_F_CALL_ORIG or * BPF_TRAMP_F_RET_FENTRY_RET - * [ argN ] + * [ arg regN ] * [ ... ] - * FP - args_off [ arg1 ] + * FP - args_off [ arg reg1 ] * - * FP - nargs_off [ regs count ] + * FP - nregs_off [ arg regs count ] * * FP - ip_off [ traced func ] BPF_TRAMP_F_IP_ARG * @@ -1626,15 +1626,23 @@ static int __arch_prepare_bpf_trampoline(struct jit= _ctx *ctx, struct bpf_tramp_i * FP - tcc_ptr_off [ tail_call_cnt_ptr ] */ =20 - if (m->nr_args > LOONGARCH_MAX_REG_ARGS) - return -ENOTSUPP; - - /* FIXME: No support of struct argument */ + /* Extra registers for struct arguments */ for (i =3D 0; i < m->nr_args; i++) { - if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) - return -ENOTSUPP; + if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) { + /* + * The struct argument size is at most 16 bytes, + * enforced by the verifier. The struct argument + * may be passed in a pair of registers if its + * size is more than 8 bytes and no more than 16 + * bytes. + */ + nregs +=3D round_up(m->arg_size[i], 8) / 8 - 1; + } } =20 + if (nregs > LOONGARCH_MAX_REG_ARGS) + return -ENOTSUPP; + if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY)) return -ENOTSUPP; =20 @@ -1648,13 +1656,12 @@ static int __arch_prepare_bpf_trampoline(struct jit= _ctx *ctx, struct bpf_tramp_i retval_off =3D stack_size; =20 /* Room of trampoline frame to store args */ - nargs =3D m->nr_args; - stack_size +=3D nargs * 8; + stack_size +=3D nregs * 8; args_off =3D stack_size; =20 /* Room of trampoline frame to store args number */ stack_size +=3D 8; - nargs_off =3D stack_size; + nregs_off =3D stack_size; =20 /* Room of trampoline frame to store ip address */ if (flags & BPF_TRAMP_F_IP_ARG) { @@ -1717,11 +1724,11 @@ static int __arch_prepare_bpf_trampoline(struct jit= _ctx *ctx, struct bpf_tramp_i emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -ip_off); } =20 - /* store nargs number */ - move_imm(ctx, LOONGARCH_GPR_T1, nargs, false); - emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -nargs_off); + /* store arg regs count */ + move_imm(ctx, LOONGARCH_GPR_T1, nregs, false); + emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -nregs_off); =20 - store_args(ctx, nargs, args_off); + store_args(ctx, nregs, args_off); =20 /* To traced function */ /* Ftrace jump skips 2 NOP instructions */ @@ -1763,7 +1770,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_c= tx *ctx, struct bpf_tramp_i } =20 if (flags & BPF_TRAMP_F_CALL_ORIG) { - restore_args(ctx, m->nr_args, args_off); + restore_args(ctx, nregs, args_off); =20 if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_FP, -tcc_ptr_off); @@ -1799,7 +1806,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_c= tx *ctx, struct bpf_tramp_i } =20 if (flags & BPF_TRAMP_F_RESTORE_REGS) - restore_args(ctx, m->nr_args, args_off); + restore_args(ctx, nregs, args_off); =20 if (save_ret) { emit_insn(ctx, ldd, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - = 8)); --=20 2.42.0 From nobody Fri Apr 17 03:01:37 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0CF3129AB05; Tue, 24 Feb 2026 07:36:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771918599; cv=none; b=LlRWFxYR72pipvLY+jl3da83p3aaINBAWsdkKDG+h3O1cBAbWow7wtwgfmaxt0mxkgirAQa5zhrcBDWej5s+13bBohCPt9HKCJ1rctWcjjuSVTOHIF6Zq+t0TftcRhvzVvBu+HeasilhnShyo9+f+j5rZ0mKBJ3lHJfBrMcCiKg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771918599; c=relaxed/simple; bh=ZHWDl5P27da+k2g3nl1uHj5zw4TRH3V2IEk/qlaxiOQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BkuS7TOGkp7Ki41UxYvXzo8DZoPjvyQ/P9pbH6u6bYCxc9eb+Yub24AqxxgY9B9RbcPShDdAMerHOehcGfdMILsxxl/i5zdBBdTebNYzAMEl47gtl5FLghYJXte9HXCKlBPy+E4DEctameNwtSDxWc4jTlJgG5bKbn2zGHkwc8E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8AxScK4VJ1p3acUAA--.63785S3; Tue, 24 Feb 2026 15:35:20 +0800 (CST) Received: from linux.localdomain (unknown [113.200.148.30]) by front1 (Coremail) with SMTP id qMiowJDxD8O0VJ1p9kxKAA--.9173S5; Tue, 24 Feb 2026 15:35:19 +0800 (CST) From: Tiezhu Yang To: Huacai Chen , Hengqi Chen Cc: loongarch@lists.linux.dev, bpf@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 3/3] LoongArch: BPF: support 12 function arguments for trampoline Date: Tue, 24 Feb 2026 15:35:15 +0800 Message-ID: <20260224073515.1273-4-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260224073515.1273-1-yangtiezhu@loongson.cn> References: <20260224073515.1273-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDxD8O0VJ1p9kxKAA--.9173S5 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoWxtr4UKFy7Zr1DGr4rZF45XFc_yoWxXr47pF 1qkan5uF18tFW7Wa97XF4UuF1YkFs3A3yY9rW7Aa92vw45ur98GayrKFnIkFy5Gr1kAr1x Cws0vrWYyF1xJ3gCm3ZEXasCq-sJn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUkFb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0cIa020Ex4CE44I27w Aqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_Jw0_WrylYx0Ex4A2jsIE 14v26r4j6F4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x 0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E 7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAIcV C0I7IYx2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF 04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7 CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x07josjUUUUUU= Content-Type: text/plain; charset="utf-8" Currently, LoongArch bpf trampoline supports up to 8 function arguments. According to the statistics from commit 473e3150e30a ("bpf, x86: allow function arguments up to 12 for TRACING"), there are over 200 functions accept 9 to 12 arguments, so add 12 arguments support for trampoline. With this patch, the following related testcases passed: sudo ./test_progs -a tracing_struct/struct_many_args sudo ./test_progs -a fentry_test/fentry_many_args sudo ./test_progs -a fexit_test/fexit_many_args Signed-off-by: Tiezhu Yang Acked-by: Hengqi Chen Tested-by: Hengqi Chen --- arch/loongarch/net/bpf_jit.c | 79 +++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index fef002bd3ffb..6037f2495cf6 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -1460,26 +1460,48 @@ int bpf_arch_text_invalidate(void *dst, size_t len) return ret; } =20 -static void store_args(struct jit_ctx *ctx, int nregs, int args_off) +static void store_args(struct jit_ctx *ctx, int nr_arg_slots, int args_off) { int i; =20 - for (i =3D 0; i < nregs; i++) { - emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off); + for (i =3D 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 */ + emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, + 16 + (i - LOONGARCH_MAX_REG_ARGS) * 8); + emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -args_off); + } args_off -=3D 8; } } =20 -static void restore_args(struct jit_ctx *ctx, int nregs, int args_off) +static void restore_args(struct jit_ctx *ctx, int nr_reg_args, int args_of= f) { int i; =20 - for (i =3D 0; i < nregs; i++) { + for (i =3D 0; i < nr_reg_args; i++) { emit_insn(ctx, ldd, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off); args_off -=3D 8; } } =20 +static void restore_stk_args(struct jit_ctx *ctx, int nr_stk_args, + int args_off, int stk_arg_off) +{ + int i; + + for (i =3D 0; i < nr_stk_args; i++) { + emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, + -(args_off - LOONGARCH_MAX_REG_ARGS * 8)); + emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, + -stk_arg_off); + args_off -=3D 8; + stk_arg_off -=3D 8; + } +} + static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l, int args_off, int retval_off, int run_ctx_off, bool save_ret) { @@ -1590,7 +1612,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_c= tx *ctx, struct bpf_tramp_i void *func_addr, u32 flags) { int i, ret, save_ret; - int stack_size, nregs =3D m->nr_args; + int stack_size, nr_arg_slots =3D 0, stk_arg_off; int retval_off, args_off, nregs_off, ip_off, run_ctx_off, sreg_off, tcc_p= tr_off; bool is_struct_ops =3D flags & BPF_TRAMP_F_INDIRECT; void *orig_call =3D func_addr; @@ -1624,25 +1646,27 @@ static int __arch_prepare_bpf_trampoline(struct jit= _ctx *ctx, struct bpf_tramp_i * FP - sreg_off [ callee saved reg ] * * FP - tcc_ptr_off [ tail_call_cnt_ptr ] + * + * [ stack_argN ] + * [ ... ] + * FP - stk_arg_off [ stack_arg1 ] BPF_TRAMP_F_CALL_ORIG */ =20 + if (m->nr_args > MAX_BPF_FUNC_ARGS) + return -ENOTSUPP; + /* Extra registers for struct arguments */ for (i =3D 0; i < m->nr_args; i++) { - if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) { - /* - * The struct argument size is at most 16 bytes, - * enforced by the verifier. The struct argument - * may be passed in a pair of registers if its - * size is more than 8 bytes and no more than 16 - * bytes. - */ - nregs +=3D round_up(m->arg_size[i], 8) / 8 - 1; - } + /* + * The struct argument size is at most 16 bytes, + * enforced by the verifier. The struct argument + * may be passed in a pair of registers if its + * size is more than 8 bytes and no more than 16 + * bytes. + */ + nr_arg_slots +=3D round_up(m->arg_size[i], 8) / 8; } =20 - if (nregs > LOONGARCH_MAX_REG_ARGS) - return -ENOTSUPP; - if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY)) return -ENOTSUPP; =20 @@ -1656,7 +1680,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_c= tx *ctx, struct bpf_tramp_i retval_off =3D stack_size; =20 /* Room of trampoline frame to store args */ - stack_size +=3D nregs * 8; + stack_size +=3D nr_arg_slots * 8; args_off =3D stack_size; =20 /* Room of trampoline frame to store args number */ @@ -1682,8 +1706,14 @@ static int __arch_prepare_bpf_trampoline(struct jit_= ctx *ctx, struct bpf_tramp_i tcc_ptr_off =3D stack_size; } =20 + if ((flags & BPF_TRAMP_F_CALL_ORIG) && (nr_arg_slots - LOONGARCH_MAX_REG_= ARGS > 0)) + stack_size +=3D (nr_arg_slots - LOONGARCH_MAX_REG_ARGS) * 8; + stack_size =3D round_up(stack_size, 16); =20 + /* Room for args on stack must be at the top of stack */ + stk_arg_off =3D stack_size; + if (is_struct_ops) { /* * For the trampoline called directly, just handle @@ -1725,10 +1755,10 @@ static int __arch_prepare_bpf_trampoline(struct jit= _ctx *ctx, struct bpf_tramp_i } =20 /* store arg regs count */ - move_imm(ctx, LOONGARCH_GPR_T1, nregs, false); + move_imm(ctx, LOONGARCH_GPR_T1, nr_arg_slots, false); emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -nregs_off); =20 - store_args(ctx, nregs, args_off); + store_args(ctx, nr_arg_slots, args_off); =20 /* To traced function */ /* Ftrace jump skips 2 NOP instructions */ @@ -1770,7 +1800,8 @@ static int __arch_prepare_bpf_trampoline(struct jit_c= tx *ctx, struct bpf_tramp_i } =20 if (flags & BPF_TRAMP_F_CALL_ORIG) { - restore_args(ctx, nregs, args_off); + restore_args(ctx, min_t(int, nr_arg_slots, LOONGARCH_MAX_REG_ARGS), args= _off); + restore_stk_args(ctx, nr_arg_slots - LOONGARCH_MAX_REG_ARGS, args_off, s= tk_arg_off); =20 if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_FP, -tcc_ptr_off); @@ -1806,7 +1837,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_c= tx *ctx, struct bpf_tramp_i } =20 if (flags & BPF_TRAMP_F_RESTORE_REGS) - restore_args(ctx, nregs, args_off); + restore_args(ctx, min_t(int, nr_arg_slots, LOONGARCH_MAX_REG_ARGS), args= _off); =20 if (save_ret) { emit_insn(ctx, ldd, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - = 8)); --=20 2.42.0