Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Hongyan Xia <hongyan.xia@transsion.com>
To: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Jiazi Li <jiazi.li@transsion.com>, Pu Hu <hupu@transsion.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [RFC PATCH 5/9] arm64/kprobes: Invoke pre/post handlers inside instrumentation
Date: Mon, 3 Aug 2026 06:11:05 +0000	[thread overview]
Message-ID: <cb605cf7-4835-4546-b6ff-b5f0b5a9b674@transsion.com> (raw)
In-Reply-To: <amzC5KrGxgfIfB-O@J2N7QTR9R3>

On 7/31/2026 11:44 PM, Mark Rutland wrote:
> On Mon, Jul 27, 2026 at 12:25:41PM +0000, Hongyan Xia wrote:
>> From: Hongyan Xia <hongyan.xia@transsion.com>
>>
>> The kprobe pre_handler() and post_handler() are arbitrary instrumentable
>> code and can themselves trace, fault, or hit other kprobes. They are
>> the only parts of the kprobe debug exception flow that legitimately
>> need instrumentation.
> 
> That doesn't explain what this patch changes, or why.
> 
> I'm fine with marking all the kprobe functions noinstr, but we don't
> need the intrumentation_{begin,end}() gunk.

Some of the helpers are quite difficult to deal with. The get_kprobe() 
has RCU debugging inside, just like kprobe_inc_nmissed_count(). We could 
further narrow down the instrumentation window, but making it completely 
noinstr might not be feasible.

> In general, it's not sound for pre_handler and post_handler to invoke
> arbitrary code, given that they could lead to recursion. We just hope
> people don't do stupid things with them.

I think this is still a big step forward. Before, we spent several weeks 
tracking down the Kprobe bug which eventually resulted in 879a6754 and 
23f851ac. It was super time-consuming to debug because 1) well, it's 
Kprobe and 2) the entire path could be instrumented and hard to narrow 
down. Now that we know such things could only happen in a couple of tiny 
helpers and the pre- and post-handlers, the surface is massively reduced 
and much easier to reason about, even if it's not 100% noinstr.

But of course, this is RFC. Would greatly appreciate better ideas. I'm 
also not keen on leaving instrumentation_{begin/end}() around.

> 
> Mark.
> 
>> Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
>> ---
>>   arch/arm64/include/asm/kprobes.h   |  9 +++------
>>   arch/arm64/kernel/probes/kprobes.c | 22 ++++++++++++++++++----
>>   2 files changed, 21 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
>> index 35ce2c94040e..a694f7d34f45 100644
>> --- a/arch/arm64/include/asm/kprobes.h
>> +++ b/arch/arm64/include/asm/kprobes.h
>> @@ -48,11 +48,8 @@ void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
>>
>>   #endif /* CONFIG_KPROBES */
>>
>> -int __kprobes kprobe_brk_handler(struct pt_regs *regs,
>> -                              unsigned long esr);
>> -int __kprobes kprobe_ss_brk_handler(struct pt_regs *regs,
>> -                              unsigned long esr);
>> -int __kprobes kretprobe_brk_handler(struct pt_regs *regs,
>> -                              unsigned long esr);
>> +int noinstr kprobe_brk_handler(struct pt_regs *regs, unsigned long esr);
>> +int noinstr kprobe_ss_brk_handler(struct pt_regs *regs, unsigned long esr);
>> +int noinstr kretprobe_brk_handler(struct pt_regs *regs, unsigned long esr);
>>
>>   #endif /* _ARM_KPROBES_H */
>> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
>> index 1b12341b2af3..e9fa66fa4217 100644
>> --- a/arch/arm64/kernel/probes/kprobes.c
>> +++ b/arch/arm64/kernel/probes/kprobes.c
>> @@ -301,8 +301,11 @@ post_kprobe_handler(struct kprobe *cur, struct kprobe_ctlblk *kcb, struct pt_reg
>>        }
>>        /* call post handler */
>>        kcb->kprobe_status = KPROBE_HIT_SSDONE;
>> +
>> +     instrumentation_begin();
>>        if (cur->post_handler)
>>                cur->post_handler(cur, regs, 0);
>> +     instrumentation_end();
>>
>>        reset_current_kprobe();
>>   }
>> @@ -359,24 +362,28 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
>>        return 0;
>>   }
>>
>> -int __kprobes
>> +int noinstr
>>   kprobe_brk_handler(struct pt_regs *regs, unsigned long esr)
>>   {
>>        struct kprobe *p, *cur_kprobe;
>>        struct kprobe_ctlblk *kcb;
>>        unsigned long addr = instruction_pointer(regs);
>> +     bool handled;
>>
>>        kcb = get_kprobe_ctlblk();
>>        cur_kprobe = kprobe_running();
>>
>> +     instrumentation_begin();
>>        p = get_kprobe((kprobe_opcode_t *) addr);
>>        if (WARN_ON_ONCE(!p)) {
>> +             instrumentation_end();
>>                /*
>>                 * Something went wrong. This BRK used an immediate reserved
>>                 * for kprobes, but we couldn't find any corresponding probe.
>>                 */
>>                return DBG_HOOK_ERROR;
>>        }
>> +     instrumentation_end();
>>
>>        if (cur_kprobe) {
>>                /* Hit a kprobe inside another kprobe */
>> @@ -387,6 +394,10 @@ kprobe_brk_handler(struct pt_regs *regs, unsigned long esr)
>>                set_current_kprobe(p);
>>                kcb->kprobe_status = KPROBE_HIT_ACTIVE;
>>
>> +             instrumentation_begin();
>> +             handled = p->pre_handler && p->pre_handler(p, regs);
>> +             instrumentation_end();
>> +
>>                /*
>>                 * If we have no pre-handler or it returned 0, we
>>                 * continue with normal processing.  If we have a
>> @@ -394,7 +405,7 @@ kprobe_brk_handler(struct pt_regs *regs, unsigned long esr)
>>                 * modify the execution path and not need to single-step
>>                 * Let's just reset current kprobe and exit.
>>                 */
>> -             if (!p->pre_handler || !p->pre_handler(p, regs))
>> +             if (!handled)
>>                        setup_singlestep(p, regs, kcb, 0);
>>                else
>>                        reset_current_kprobe();
>> @@ -403,7 +414,7 @@ kprobe_brk_handler(struct pt_regs *regs, unsigned long esr)
>>        return DBG_HOOK_HANDLED;
>>   }
>>
>> -int __kprobes
>> +int noinstr
>>   kprobe_ss_brk_handler(struct pt_regs *regs, unsigned long esr)
>>   {
>>        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
>> @@ -422,13 +433,16 @@ kprobe_ss_brk_handler(struct pt_regs *regs, unsigned long esr)
>>        return DBG_HOOK_ERROR;
>>   }
>>
>> -int __kprobes
>> +int noinstr
>>   kretprobe_brk_handler(struct pt_regs *regs, unsigned long esr)
>>   {
>>        if (regs->pc != (unsigned long)__kretprobe_trampoline)
>>                return DBG_HOOK_ERROR;
>>
>> +     instrumentation_begin();
>>        regs->pc = kretprobe_trampoline_handler(regs, (void *)regs->regs[29]);
>> +     instrumentation_end();
>> +
>>        return DBG_HOOK_HANDLED;
>>   }
>>
>> --
>> 2.47.3
>>


  reply	other threads:[~2026-08-03  6:11 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1785153469.git.hongyan.xia@transsion.com>
2026-07-27 12:25 ` [RFC PATCH 1/9] arm64/entry: Bound certain debug exception paths in instrumentation windows Hongyan Xia
2026-07-31 14:41   ` Mark Rutland
2026-08-03  3:42     ` Hongyan Xia
2026-07-27 12:25 ` [RFC PATCH 2/9] arm64/entry: Make debug_exception_enter/exit() noinstr Hongyan Xia
2026-07-31 14:43   ` Mark Rutland
2026-07-27 12:25 ` [RFC PATCH 3/9] arm64/debug-monitors: Make do_el1_brk64()/do_el1_softstep() noinstr Hongyan Xia
2026-07-31 15:25   ` Mark Rutland
2026-08-03  3:54     ` Hongyan Xia
2026-07-27 12:25 ` [RFC PATCH 4/9] arm64/kprobes: Make the single-step machinery noinstr Hongyan Xia
2026-07-31 15:38   ` Mark Rutland
2026-08-03  4:31     ` Hongyan Xia
2026-07-27 12:25 ` [RFC PATCH 5/9] arm64/kprobes: Invoke pre/post handlers inside instrumentation Hongyan Xia
2026-07-31 15:44   ` Mark Rutland
2026-08-03  6:11     ` Hongyan Xia [this message]
2026-07-27 12:25 ` [RFC PATCH 6/9] arm64/kprobes: Make kprobe_fault_handler() noinstr Hongyan Xia
2026-07-31 15:57   ` Mark Rutland
2026-08-03  6:40     ` Hongyan Xia
2026-07-27 12:25 ` [RFC PATCH 7/9] arm64/kprobes: Drop the KPROBE_HIT_SS reentry special case Hongyan Xia
2026-07-27 12:25 ` [RFC PATCH 8/9] arm64/kprobes: Drop the XOL single-step fault PC check Hongyan Xia
2026-07-31 16:12   ` Mark Rutland
2026-07-27 12:25 ` [RFC PATCH 9/9] arm64/debug: Mark debug exception helpers __always_inline Hongyan Xia
2026-07-27 19:22   ` Nick Desaulniers
2026-07-27 21:49     ` Will Deacon
2026-07-28  2:03     ` Hongyan Xia
2026-07-29 18:08   ` Steven Rostedt
2026-07-30  0:03     ` Masami Hiramatsu
2026-07-30 11:50       ` Hongyan Xia
2026-07-31 16:15   ` Mark Rutland

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=cb605cf7-4835-4546-b6ff-b5f0b5a9b674@transsion.com \
    --to=hongyan.xia@transsion.com \
    --cc=catalin.marinas@arm.com \
    --cc=hupu@transsion.com \
    --cc=jiazi.li@transsion.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mhiramat@kernel.org \
    --cc=will@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox