From: Chenghao Duan <duanchenghao@kylinos.cn>
To: Hengqi Chen <hengqi.chen@gmail.com>
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
yangtiezhu@loongson.cn, chenhuacai@kernel.org,
martin.lau@linux.dev, eddyz87@gmail.com, song@kernel.org,
yonghong.song@linux.dev, john.fastabend@gmail.com,
kpsingh@kernel.org, sdf@fomichev.me, haoluo@google.com,
jolsa@kernel.org, kernel@xen0n.name,
linux-kernel@vger.kernel.org, loongarch@lists.linux.dev,
bpf@vger.kernel.org, guodongtai@kylinos.cn,
youling.tang@linux.dev, jianghaoran@kylinos.cn
Subject: Re: [PATCH v3 4/5] LoongArch: BPF: Add bpf_arch_xxxxx support for Loongarch
Date: Fri, 18 Jul 2025 10:16:58 +0800 [thread overview]
Message-ID: <20250718021658.GA203872@chenghao-pc> (raw)
In-Reply-To: <CAEyhmHTpJ0OKbW1QEFV+XMxCC9kL2eSwKMkk7=YyLprjNxc8iA@mail.gmail.com>
On Thu, Jul 17, 2025 at 06:12:55PM +0800, Hengqi Chen wrote:
> On Thu, Jul 17, 2025 at 5:27 PM Chenghao Duan <duanchenghao@kylinos.cn> wrote:
> >
> > On Wed, Jul 16, 2025 at 08:21:59PM +0800, Hengqi Chen wrote:
> > > On Wed, Jul 9, 2025 at 1:50 PM Chenghao Duan <duanchenghao@kylinos.cn> wrote:
> > > >
> > > > Implement the functions of bpf_arch_text_poke, bpf_arch_text_copy, and
> > > > bpf_arch_text_invalidate on the LoongArch architecture.
> > > >
> > > > On LoongArch, since symbol addresses in the direct mapping
> > > > region cannot be reached via relative jump instructions from the paged
> > > > mapping region, we use the move_imm+jirl instruction pair as absolute
> > > > jump instructions. These require 2-5 instructions, so we reserve 5 NOP
> > > > instructions in the program as placeholders for function jumps.
> > > >
> > > > Co-developed-by: George Guo <guodongtai@kylinos.cn>
> > > > Signed-off-by: George Guo <guodongtai@kylinos.cn>
> > > > Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
> > > > ---
> > > > arch/loongarch/include/asm/inst.h | 1 +
> > > > arch/loongarch/kernel/inst.c | 32 +++++++++++
> > > > arch/loongarch/net/bpf_jit.c | 90 +++++++++++++++++++++++++++++++
> > > > 3 files changed, 123 insertions(+)
> > > >
> > > > diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h
> > > > index 2ae96a35d..88bb73e46 100644
> > > > --- a/arch/loongarch/include/asm/inst.h
> > > > +++ b/arch/loongarch/include/asm/inst.h
> > > > @@ -497,6 +497,7 @@ void arch_simulate_insn(union loongarch_instruction insn, struct pt_regs *regs);
> > > > int larch_insn_read(void *addr, u32 *insnp);
> > > > int larch_insn_write(void *addr, u32 insn);
> > > > int larch_insn_patch_text(void *addr, u32 insn);
> > > > +int larch_insn_text_copy(void *dst, void *src, size_t len);
> > > >
> > > > u32 larch_insn_gen_nop(void);
> > > > u32 larch_insn_gen_b(unsigned long pc, unsigned long dest);
> > > > diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c
> > > > index 674e3b322..8d6594968 100644
> > > > --- a/arch/loongarch/kernel/inst.c
> > > > +++ b/arch/loongarch/kernel/inst.c
> > > > @@ -4,6 +4,7 @@
> > > > */
> > > > #include <linux/sizes.h>
> > > > #include <linux/uaccess.h>
> > > > +#include <linux/set_memory.h>
> > > >
> > > > #include <asm/cacheflush.h>
> > > > #include <asm/inst.h>
> > > > @@ -218,6 +219,37 @@ int larch_insn_patch_text(void *addr, u32 insn)
> > > > return ret;
> > > > }
> > > >
> > > > +int larch_insn_text_copy(void *dst, void *src, size_t len)
> > > > +{
> > > > + unsigned long flags;
> > > > + size_t wlen = 0;
> > > > + size_t size;
> > > > + void *ptr;
> > > > + int ret = 0;
> > > > +
> > > > + set_memory_rw((unsigned long)dst, round_up(len, PAGE_SIZE) / PAGE_SIZE);
> > > > + raw_spin_lock_irqsave(&patch_lock, flags);
> > > > + while (wlen < len) {
> > > > + ptr = dst + wlen;
> > > > + size = min_t(size_t, PAGE_SIZE - offset_in_page(ptr),
> > > > + len - wlen);
> > > > +
> > > > + ret = copy_to_kernel_nofault(ptr, src + wlen, size);
> > > > + if (ret) {
> > > > + pr_err("%s: operation failed\n", __func__);
> > > > + break;
> > > > + }
> > > > + wlen += size;
> > > > + }
> > >
> > > Again, why do you do copy_to_kernel_nofault() in a loop ?
> >
> > The while loop processes all sizes. I referred to how ARM64 and
> > RISC-V64 handle this using loops as well.
>
> Any pointers ?
I didn't understand what you meant.
>
> >
> > > This larch_insn_text_copy() can be part of the first patch like
> > > larch_insn_gen_{beq,bne}. WDYT ?
> >
> > From my perspective, it is acceptable to include both
> > larch_insn_text_copy and larch_insn_gen_{beq,bne} in the same patch,
> > or place them in the bpf_arch_xxxx patch. larch_insn_text_copy is
> > solely used for BPF; the application scope of larch_insn_gen_{beq,bne}
> > is not limited to BPF.
> >
>
> The implementation of larch_insn_text_copy() seems generic.
The use of larch_insn_text_copy() requires page_size alignment.
Currently, only the size of the trampoline is page-aligned.
>
> > >
> > > > + raw_spin_unlock_irqrestore(&patch_lock, flags);
> > > > + set_memory_rox((unsigned long)dst, round_up(len, PAGE_SIZE) / PAGE_SIZE);
> > > > +
> > > > + if (!ret)
> > > > + flush_icache_range((unsigned long)dst, (unsigned long)dst + len);
> > > > +
> > > > + return ret;
> > > > +}
> > > > +
> > > > u32 larch_insn_gen_nop(void)
> > > > {
> > > > return INSN_NOP;
> > > > diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
> > > > index 7032f11d3..9cb01f0b0 100644
> > > > --- a/arch/loongarch/net/bpf_jit.c
> > > > +++ b/arch/loongarch/net/bpf_jit.c
> > > > @@ -4,6 +4,7 @@
> > > > *
> > > > * Copyright (C) 2022 Loongson Technology Corporation Limited
> > > > */
> > > > +#include <linux/memory.h>
> > > > #include "bpf_jit.h"
> > > >
> > > > #define REG_TCC LOONGARCH_GPR_A6
> > > > @@ -1367,3 +1368,92 @@ bool bpf_jit_supports_subprog_tailcalls(void)
> > > > {
> > > > return true;
> > > > }
> > > > +
> > > > +static int emit_jump_and_link(struct jit_ctx *ctx, u8 rd, u64 ip, u64 target)
> > > > +{
> > > > + s64 offset = (s64)(target - ip);
> > > > +
> > > > + if (offset && (offset >= -SZ_128M && offset < SZ_128M)) {
> > > > + emit_insn(ctx, bl, offset >> 2);
> > > > + } else {
> > > > + move_imm(ctx, LOONGARCH_GPR_T1, target, false);
> > > > + emit_insn(ctx, jirl, rd, LOONGARCH_GPR_T1, 0);
> > > > + }
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +static int gen_jump_or_nops(void *target, void *ip, u32 *insns, bool is_call)
> > > > +{
> > > > + struct jit_ctx ctx;
> > > > +
> > > > + ctx.idx = 0;
> > > > + ctx.image = (union loongarch_instruction *)insns;
> > > > +
> > > > + if (!target) {
> > > > + emit_insn((&ctx), nop);
> > > > + emit_insn((&ctx), nop);
> > > > + return 0;
> > > > + }
> > > > +
> > > > + return emit_jump_and_link(&ctx, is_call ? LOONGARCH_GPR_T0 : LOONGARCH_GPR_ZERO,
> > > > + (unsigned long)ip, (unsigned long)target);
> > > > +}
> > > > +
> > > > +int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
> > > > + void *old_addr, void *new_addr)
> > > > +{
> > > > + u32 old_insns[5] = {[0 ... 4] = INSN_NOP};
> > > > + u32 new_insns[5] = {[0 ... 4] = INSN_NOP};
> > > > + bool is_call = poke_type == BPF_MOD_CALL;
> > > > + int ret;
> > > > +
> > > > + if (!is_kernel_text((unsigned long)ip) &&
> > > > + !is_bpf_text_address((unsigned long)ip))
> > > > + return -ENOTSUPP;
> > > > +
> > > > + ret = gen_jump_or_nops(old_addr, ip, old_insns, is_call);
> > > > + if (ret)
> > > > + return ret;
> > > > +
> > > > + if (memcmp(ip, old_insns, 5 * 4))
> > > > + return -EFAULT;
> > > > +
> > > > + ret = gen_jump_or_nops(new_addr, ip, new_insns, is_call);
> > > > + if (ret)
> > > > + return ret;
> > > > +
> > > > + mutex_lock(&text_mutex);
> > > > + if (memcmp(ip, new_insns, 5 * 4))
> > > > + ret = larch_insn_text_copy(ip, new_insns, 5 * 4);
> > > > + mutex_unlock(&text_mutex);
> > > > + return ret;
> > > > +}
> > > > +
> > > > +int bpf_arch_text_invalidate(void *dst, size_t len)
> > > > +{
> > > > + int i;
> > > > + int ret = 0;
> > > > + u32 *inst;
> > > > +
> > > > + inst = kvmalloc(len, GFP_KERNEL);
> > > > + if (!inst)
> > > > + return -ENOMEM;
> > > > +
> > > > + for (i = 0; i < (len/sizeof(u32)); i++)
> > > > + inst[i] = INSN_BREAK;
> > > > +
> > > > + if (larch_insn_text_copy(dst, inst, len))
> > > > + ret = -EINVAL;
> > > > +
> > > > + kvfree(inst);
> > > > + return ret;
> > > > +}
> > > > +
> > > > +void *bpf_arch_text_copy(void *dst, void *src, size_t len)
> > > > +{
> > > > + if (larch_insn_text_copy(dst, src, len))
> > > > + return ERR_PTR(-EINVAL);
> > > > +
> > > > + return dst;
> > > > +}
> > > > --
> > > > 2.43.0
> > > >
next prev parent reply other threads:[~2025-07-18 2:17 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-09 5:50 [PATCH v3 0/5] Support trampoline for LoongArch Chenghao Duan
2025-07-09 5:50 ` [PATCH v3 1/5] LoongArch: Add the function to generate the beq and bne assembly instructions Chenghao Duan
2025-07-16 11:33 ` Hengqi Chen
2025-07-09 5:50 ` [PATCH v3 2/5] LoongArch: BPF: Update the code to rename validate_code to validate_ctx Chenghao Duan
2025-07-16 11:55 ` Hengqi Chen
2025-07-17 9:46 ` Chenghao Duan
2025-07-09 5:50 ` [PATCH v3 3/5] LoongArch: BPF: Add EXECMEM_BPF memory to execmem subsystem Chenghao Duan
2025-07-09 15:23 ` Huacai Chen
2025-07-10 7:23 ` Chenghao Duan
2025-07-09 5:50 ` [PATCH v3 4/5] LoongArch: BPF: Add bpf_arch_xxxxx support for Loongarch Chenghao Duan
2025-07-16 12:21 ` Hengqi Chen
2025-07-17 9:27 ` Chenghao Duan
2025-07-17 10:12 ` Hengqi Chen
2025-07-18 2:16 ` Chenghao Duan [this message]
2025-07-21 1:38 ` Hengqi Chen
2025-07-21 7:59 ` Chenghao Duan
2025-07-16 18:41 ` Vincent Li
2025-07-18 23:08 ` Vincent Li
2025-07-09 5:50 ` [PATCH v3 5/5] LoongArch: BPF: Add bpf trampoline " Chenghao Duan
2025-07-09 17:19 ` kernel test robot
2025-07-09 19:08 ` Vincent Li
2025-07-10 8:04 ` Chenghao Duan
2025-07-10 15:03 ` Vincent Li
2025-07-15 21:19 ` Vincent Li
2025-07-15 21:54 ` Vincent Li
2025-07-16 3:11 ` Vincent Li
2025-07-16 14:51 ` Vincent Li
2025-07-16 15:35 ` Vincent Li
2025-07-16 22:15 ` Vincent Li
2025-07-17 2:46 ` Chenghao Duan
2025-07-17 13:27 ` Vincent Li
2025-07-17 14:53 ` Vincent Li
2025-07-16 1:53 ` Chenghao Duan
2025-07-16 2:23 ` Vincent Li
2025-07-16 12:32 ` Hengqi Chen
2025-07-17 9:43 ` Chenghao Duan
2025-07-10 7:29 ` [PATCH v3 0/5] Support trampoline for LoongArch Huacai Chen
2025-07-14 8:55 ` Tiezhu Yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250718021658.GA203872@chenghao-pc \
--to=duanchenghao@kylinos.cn \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=chenhuacai@kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=guodongtai@kylinos.cn \
--cc=haoluo@google.com \
--cc=hengqi.chen@gmail.com \
--cc=jianghaoran@kylinos.cn \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kernel@xen0n.name \
--cc=kpsingh@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=loongarch@lists.linux.dev \
--cc=martin.lau@linux.dev \
--cc=sdf@fomichev.me \
--cc=song@kernel.org \
--cc=yangtiezhu@loongson.cn \
--cc=yonghong.song@linux.dev \
--cc=youling.tang@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.