Hi Jisheng, On Mon, 12 Apr 2021 17:41:01 +0800 Jisheng Zhang <[email protected]> wrote:
> If instruction being single stepped caused a page fault, the kprobes > is cancelled to let the page fault handler continue as a normal page > fault. But the local irqflags are disabled so cpu will restore pstate > with DAIF masked. After pagefault is serviced, the kprobes is > triggerred again, we overwrite the saved_irqflag by calling > kprobes_save_local_irqflag(). NOTE, DAIF is masked in this new saved > irqflag. After kprobes is serviced, the cpu pstate is retored with > DAIF masked. > > This patch is inspired by one patch for riscv from Liao Chang. Thanks for pointing it out. But I think kprobes_restore_local_irqflag() is also needed for kcb->kprobe_status == KPROBE_REENTER case...no. This is more complicated. In the reenter case, I think we have to retry the kpreprobe_fault_handler() with recovered previous kprobes so that it can handle page fault in its handler. Hmm, RISC-V and other code also needs same fix. Thank you, > > Signed-off-by: Jisheng Zhang <[email protected]> > --- > arch/arm64/kernel/probes/kprobes.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/arch/arm64/kernel/probes/kprobes.c > b/arch/arm64/kernel/probes/kprobes.c > index 66aac2881ba8..85645b2b0c7a 100644 > --- a/arch/arm64/kernel/probes/kprobes.c > +++ b/arch/arm64/kernel/probes/kprobes.c > @@ -267,10 +267,12 @@ int __kprobes kprobe_fault_handler(struct pt_regs > *regs, unsigned int fsr) > if (!instruction_pointer(regs)) > BUG(); > > - if (kcb->kprobe_status == KPROBE_REENTER) > + if (kcb->kprobe_status == KPROBE_REENTER) { > restore_previous_kprobe(kcb); > - else > + } else { > + kprobes_restore_local_irqflag(kcb, regs); > reset_current_kprobe(); > + } > > break; > case KPROBE_HIT_ACTIVE: > -- > 2.31.0 > -- Masami Hiramatsu <[email protected]>

