Thread (15 messages) 15 messages, 4 authors, 1d ago

Re: [RFC v3 2/2] arm64: kprobes: Allow reentering kprobes while single-stepping

From: Hongyan Xia <hidden>
Date: 2026-07-17 11:31:36
Also in: linux-arm-kernel, lkml

On 7/17/2026 7:01 PM, Will Deacon wrote:
On Fri, Jul 17, 2026 at 01:51:12AM +0000, Hongyan Xia wrote:
quoted
On 7/16/2026 11:20 PM, Will Deacon wrote:
quoted
On Thu, Jul 16, 2026 at 02:38:58PM +0000, Pu Hu wrote:
quoted
On 7/16/2026 9:24 PM, Will Deacon wrote:
quoted
On Fri, Jul 10, 2026 at 06:32:55AM +0000, Pu Hu wrote:
quoted
From: Pu Hu <redacted>

A kprobe can be hit while another kprobe is in KPROBE_HIT_SS state. This
can happen when tracing or perf code runs from the debug exception path
while the first kprobe is preparing or executing its out-of-line
single-step instruction.
I don't understand this part. The single-step runs with debug exceptions
disabled (kprobes_save_local_irqflag() sets PSTATE.D) so how do we end
up taking one?
You are right that the single-step runs with debug exceptions disabled.
However, the case I was referring to is not a hardware breakpoint or a
software-step exception, but another Breakpoint Instruction exception
generated by executing a BRK instruction. A BRK instruction exception is
not masked by PSTATE.D, so it can still be taken while handling a kprobe.

As far as I understand the architecture, there are two different cases here:

     - Breakpoint Instruction exceptions, generated by executing a BRK
       instruction.
     - Breakpoint exceptions, generated by the debug logic, for example by
       programmed breakpoint registers.

PSTATE.D masks debug exceptions such as hardware breakpoints,
watchpoints and software-step exceptions, but it does not mask
Breakpoint Instruction exceptions generated by BRK. This also seems
consistent with the pseudocode for BRK,
Arch64.SoftwareBreakpoint(imm16), which does not appear to check
PSTATE.D before taking the exception.

Therefore, even if kprobes_save_local_irqflag() sets PSTATE.D while
handling the first kprobe, if the code executed from that path reaches
another instruction patched with BRK, it can still take a Breakpoint
Instruction exception. In other words, the nested case I mentioned is
another kprobe BRK being hit, not a hardware debug exception or a
software-step exception.
Yes, that's correct, but if we're doing the out-of-line step, how do we
end up executing a BRK? Or are you saying that it's the kprobes
BRK64_OPCODE_KPROBES_SS instruction that we use to implement the
single-step that is the problem? If so, how does taking that exception
result in us executing tracing or perf code?

Sorry for all the questions, I just haven't understood what's going on
here from the commit message.
The key is that, when you use 'perf --call-graph dwarf' to sample
certain events, kernel perf code will sample a piece of user stack each
time those events are hit, and copy_to/from_user() triggers page faults.
Say you are profiling preempt_enable events:

1st BRK -> preempt_disable() -> debug_exception() -> set SS state ->
preempt_enable() -> triggers perf -> perf_sample() -> sample user stack
using copy_to/from_user() -> page fault or 2nd BRK on the page fault path.

The key is perf sampling the user stack while the 1st BRK is still
running. When a page fault is hit, a can of worms is released, including
a possible 2nd BRK.
Thanks. So perf is run synchronously from the debug exception entry path,
Yes, exactly.
rather than because of a second exception taking place. Got it. But then
it sounds like we should really make the debug exception handling path (at
least, the part that runs for handling the kprobe step) noinstr to avoid
getting into this state to begin with. Is that practical?
Not sure about making the whole path noinstr (@Masami might have a 
better opinion on this than me). Personally I don't mind either 
disallowing it or making it correct.

But it might be a good idea not to diverge too much between ISAs. This 
patch is pretty much mirroring what the x86 side handles this situation.
Will
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help