arch/loongarch/kernel/kprobes.c | 3 +++ 1 file changed, 3 insertions(+)
LoongArch uses break 11 for the breakpoint placed after an instruction
that Kprobes executes out of line. Since userspace can issue the same
break instruction, do_bp() can reach kprobe_singlestep_handler() when
there is no current probe.
The handler returns false in this case, but first calls
preempt_enable_no_resched(). The corresponding preempt_disable() is done
by kprobe_breakpoint_handler() on a real Kprobe hit, so it has not run
here. As a result, an ordinary userspace breakpoint underflows the
current task's preempt count.
This also makes in_interrupt() return true until the task schedules. One
visible consequence is socket cgroup attribution: cgroup_sk_alloc()
treats the allocation as interrupt context and assigns the socket to the
root cgroup. A socket opened from the SIGTRAP handler can then avoid a
BPF_CGROUP_INET_SOCK_CREATE policy attached to the task's own cgroup.
Return as soon as kprobe_running() reports no active probe.
The same check appeared in [PATCH v10 2/4] of the original LoongArch
Kprobes series, but was dropped before the feature reached mainline.
Link: https://patchew.org/linux/1670575981-14389-1-git-send-email-yangtiezhu%40loongson.cn/1670575981-14389-3-git-send-email-yangtiezhu%40loongson.cn/
Fixes: 6d4cc40fb5f5 ("LoongArch: Add kprobes support")
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
---
arch/loongarch/kernel/kprobes.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/loongarch/kernel/kprobes.c b/arch/loongarch/kernel/kprobes.c
index 1985ed30dd16f..ddfefea174727 100644
--- a/arch/loongarch/kernel/kprobes.c
+++ b/arch/loongarch/kernel/kprobes.c
@@ -275,6 +275,9 @@ bool kprobe_singlestep_handler(struct pt_regs *regs)
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
unsigned long addr = instruction_pointer(regs);
+ if (!cur)
+ return false;
+
if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
((unsigned long)&cur->ainsn.insn[1] == addr)) {
restore_local_irqflag(kcb, regs);
--
2.47.3
Applied, thanks.
Huacai
On Mon, Aug 24, 2026 at 5:19 AM Jérémy Jean
<Jeremy.Jean@oss.cyber.gouv.fr> wrote:
>
> LoongArch uses break 11 for the breakpoint placed after an instruction
> that Kprobes executes out of line. Since userspace can issue the same
> break instruction, do_bp() can reach kprobe_singlestep_handler() when
> there is no current probe.
>
> The handler returns false in this case, but first calls
> preempt_enable_no_resched(). The corresponding preempt_disable() is done
> by kprobe_breakpoint_handler() on a real Kprobe hit, so it has not run
> here. As a result, an ordinary userspace breakpoint underflows the
> current task's preempt count.
>
> This also makes in_interrupt() return true until the task schedules. One
> visible consequence is socket cgroup attribution: cgroup_sk_alloc()
> treats the allocation as interrupt context and assigns the socket to the
> root cgroup. A socket opened from the SIGTRAP handler can then avoid a
> BPF_CGROUP_INET_SOCK_CREATE policy attached to the task's own cgroup.
>
> Return as soon as kprobe_running() reports no active probe.
>
> The same check appeared in [PATCH v10 2/4] of the original LoongArch
> Kprobes series, but was dropped before the feature reached mainline.
>
> Link: https://patchew.org/linux/1670575981-14389-1-git-send-email-yangtiezhu%40loongson.cn/1670575981-14389-3-git-send-email-yangtiezhu%40loongson.cn/
> Fixes: 6d4cc40fb5f5 ("LoongArch: Add kprobes support")
> Assisted-by: Codex:gpt-5
> Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
> ---
> arch/loongarch/kernel/kprobes.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/arch/loongarch/kernel/kprobes.c b/arch/loongarch/kernel/kprobes.c
> index 1985ed30dd16f..ddfefea174727 100644
> --- a/arch/loongarch/kernel/kprobes.c
> +++ b/arch/loongarch/kernel/kprobes.c
> @@ -275,6 +275,9 @@ bool kprobe_singlestep_handler(struct pt_regs *regs)
> struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> unsigned long addr = instruction_pointer(regs);
>
> + if (!cur)
> + return false;
> +
> if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
> ((unsigned long)&cur->ainsn.insn[1] == addr)) {
> restore_local_irqflag(kcb, regs);
> --
> 2.47.3
>
Hello, > @@ -275,6 +275,9 @@ bool kprobe_singlestep_handler(struct pt_regs *regs) > struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); > unsigned long addr = instruction_pointer(regs); > > + if (!cur) > + return false; > + This patch looks good to me. BRs Wentao Guan
On 23 August 2026 22:18:23 BST, "Jérémy Jean"
<Jeremy.Jean@oss.cyber.gouv.fr> wrote:
>LoongArch uses break 11 for the breakpoint placed after an instruction
>that Kprobes executes out of line. Since userspace can issue the same
>break instruction, do_bp() can reach kprobe_singlestep_handler() when
>there is no current probe.
>
Intresting
>The handler returns false in this case, but first calls
>preempt_enable_no_resched(). The corresponding preempt_disable() is done
>by kprobe_breakpoint_handler() on a real Kprobe hit, so it has not run
>here. As a result, an ordinary userspace breakpoint underflows the
>current task's preempt count.
>
checked. Guess that's true
>This also makes in_interrupt() return true until the task schedules. One
>visible consequence is socket cgroup attribution: cgroup_sk_alloc()
>treats the allocation as interrupt context and assigns the socket to the
>root cgroup. A socket opened from the SIGTRAP handler can then avoid a
>BPF_CGROUP_INET_SOCK_CREATE policy attached to the task's own cgroup.
>
>Return as soon as kprobe_running() reports no active probe.
>
Ideal.
>The same check appeared in [PATCH v10 2/4] of the original LoongArch
>Kprobes series, but was dropped before the feature reached mainline.
>
wonder why.
>Link: https://patchew.org/linux/1670575981-14389-1-git-send-email-yangtiezhu%40loongson.cn/1670575981-14389-3-git-send-email-yangtiezhu%40loongson.cn/
Lore please.
>Fixes: 6d4cc40fb5f5 ("LoongArch: Add kprobes support")
>Assisted-by: Codex:gpt-5
5.6-sol? Or normal GPT 5?
>Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
>---
> arch/loongarch/kernel/kprobes.c | 3 +++
> 1 file changed, 3 insertions(+)
>
>diff --git a/arch/loongarch/kernel/kprobes.c b/arch/loongarch/kernel/kprobes.c
>index 1985ed30dd16f..ddfefea174727 100644
>--- a/arch/loongarch/kernel/kprobes.c
>+++ b/arch/loongarch/kernel/kprobes.c
>@@ -275,6 +275,9 @@ bool kprobe_singlestep_handler(struct pt_regs *regs)
> struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> unsigned long addr = instruction_pointer(regs);
>
>+ if (!cur)
>+ return false;
comment?
/* do_bp() can reach
* kprobe_singlestep_handler() when
* there is no current probe, which
* may cause issues.
*/
My one isn't perfect, but feel free to bikeshed
Well, I'm not a loongarch expert, but I am good with kprobes, hence this
review.
>+
> if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
> ((unsigned long)&cur->ainsn.insn[1] == addr)) {
> restore_local_irqflag(kcb, regs);
>
Thanks!
© 2016 - 2026 Red Hat, Inc.