On Wed, 8 Jul 2026 08:55:37 +0000 Hongyan Xia <[email protected]> wrote:
> On 7/8/2026 3:42 PM, Masami Hiramatsu wrote: > > On Wed, 8 Jul 2026 05:57:24 +0000 > > Hongyan Xia <[email protected]> wrote: > > > >> Hi Masami, > >> > >> On 7/8/2026 8:46 AM, Masami Hiramatsu wrote: > >>> On Mon, 6 Jul 2026 08:36:48 +0000 > >>> Pu Hu <[email protected]> wrote: > >>> > >>>> From: Pu Hu <[email protected]> > >>>> > >>>> kprobe_fault_handler() handles faults taken while kprobes is in > >>>> KPROBE_HIT_SS or KPROBE_REENTER state as faults caused by the > >>>> single-stepped instruction. > >>>> > >>>> That assumption is not always true. While a kprobe is preparing or > >>>> executing the out-of-line single-step instruction, other code may run > >>>> in that window. For example, perf or trace code can be invoked from the > >>>> debug exception path and may take a fault of its own. In that case the > >>>> fault did not happen on the kprobe XOL instruction, but the kprobe fault > >>>> handler may still try to recover it as a kprobe single-step fault. > >>>> > >>>> This can corrupt the exception recovery flow and leave the real fault to > >>>> be handled with a wrong PC. A typical reproducer is running simpleperf > >>>> with preemptirq tracepoints and dwarf callchains while a kprobe is > >>>> installed on a frequently executed kernel function. > >>>> > >>>> Fix this by handling faults in KPROBE_HIT_SS/KPROBE_REENTER only when > >>>> the faulting PC points at the current kprobe's XOL instruction. Faults > >>>> from any other PC are left to the normal fault handling path. > >>>> > >>>> This follows the same idea as the x86 fix in commit 6381c24cd6d5 > >>>> ("kprobes/x86: Fix page-fault handling logic"). > >>>> > >>>> Signed-off-by: Pu Hu <[email protected]> > >>>> Signed-off-by: Hongyan Xia <[email protected]> > >>>> --- > >>>> arch/arm64/kernel/probes/kprobes.c | 14 ++++++++++++++ > >>>> 1 file changed, 14 insertions(+) > >>>> > >>>> diff --git a/arch/arm64/kernel/probes/kprobes.c > >>>> b/arch/arm64/kernel/probes/kprobes.c > >>>> index 43a0361a8bf0..e4d2852ce2fb 100644 > >>>> --- a/arch/arm64/kernel/probes/kprobes.c > >>>> +++ b/arch/arm64/kernel/probes/kprobes.c > >>>> @@ -285,6 +285,20 @@ int __kprobes kprobe_fault_handler(struct pt_regs > >>>> *regs, unsigned int fsr) > >>>> switch (kcb->kprobe_status) { > >>>> case KPROBE_HIT_SS: > >>>> case KPROBE_REENTER: > >>>> + /* > >>>> + * A fault taken while a kprobe is single-stepping is not > >>>> + * necessarily caused by the instruction in the XOL slot. > >>>> For > >>>> + * example, tracing or perf code running in this window > >>>> may take > >>>> + * an unrelated fault. > >>>> + * > >>>> + * Handle the fault here only when the faulting PC is the > >>>> XOL > >>>> + * instruction of the current kprobe. Otherwise let the > >>>> normal > >>>> + * fault handling path deal with it. > >>>> + */ > >>>> + if (cur->ainsn.xol_insn && > >>>> + instruction_pointer(regs) != (unsigned > >>>> long)cur->ainsn.xol_insn) > >>>> + break; > >>> > >>> Can you check Sashiko's comments[1]? > >>> > >>> [1] > >>> https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com?part=1 > >>> > >>> It seems that it complains about simulated kprobe's case. > >>> In that case, cur->ainsn.xol_insn == NULL. The simulation should be done > >>> in the kprobe context (which is a debug trap). I'm not sure the arm64 > >>> can cause NMI in that context, but if it happens and causes a fault, > >>> it may cause a problem. > >>> > >>> So I think we can just ignore the fault on the simulated kprobes. > >>> > >>> To ensure that, you can just add: > >>> > >>> if (cur && !cur->ainsn.xol_insn) > >>> return 0; > >>> > >>> at the entry of this function. (and remove redundant cur->ainsn.xol_insn > >>> check) > >> > >> Right, both cases: > >> > >> 1. single-step XOL > >> 2. simulated > >> > >> have this problem and this patch fixed 1. 2 remains unchanged. > >> > >> Ideally we should fix both, but the simulated case seems more > >> complicated, and at least we didn't make things worse for 2. So I wonder > >> if we can analyze 2 more thoroughly and fix it in a separate patch. > > > > OK, but basically this fault handler is only for the SS XOL, > > not for simulated one (as same as x86). So just skip the > > simulated case is enough in this patch. > > (Note that x86 also have simulated path, and that is not handled > > by the fault handler) > > Hmm, what happens if the original PC is a simulated instruction that has > a recoverable ex_table entry that handles potential page fault, That should never happen. BPF trampoline code may populate extable entries, but kprobe doesn't. For the simulated instruction, as far as I can see, there are 2 operations - simulate_ldr_literal - simulate_ldrsw_literal will involve the memory access and both are accessing PC-relative kernel data, which should be mapped. load_addr = addr + ldr_displacement(opcode); ... set_x_reg(regs, xn, READ_ONCE(*(u64 *)load_addr)); this directly accessing the memory without using extable. > and this > PC also has an attached kprobe? You meant that putting kprobes in simulate_* functions? Those have __kprobes attribute, so kprobe can not probe it. (It should use NOKPROBE_SYMBOL...) > Then the simulated case should be able > to enter kprobe_fault_handler()? > > .ex_table: > insn foo, handler bar > > foo: > LDR symbol # Load PC-relative. Simulated. Kprobe attached. > ret > > When foo is called and the kprobe fires, it enters simulated path but > then LDR triggers a page fault. It then enters kprobe_fault_handler() to > fixup the PC. Then the fixup_exception() of the normal page fault finds > the ex_table entry and this case is successfully handled? To do that, you need to update the simulate_ldr* to use uaccess API (_ASM_EXTABLE_UACCESS* macros) AND allow kprobes to probe those functions. > > Looks like this handler can be entered by simulated instructions? Or > this is only theoretical and whoever arrange code like this should be > fired immediately? So the simulated instructions never cause fault, or if it causes a fault that means the original code has a bug. (Of course there is room to improve the bug message so that it decodes the address probed by kprobe when a bug occurs.) Thank you, -- Masami Hiramatsu (Google) <[email protected]>
