From: Vladimir Murzin <vladimir.murzin@arm.com> driver inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/10041 ---------------------------------------------------------------------- Kprobes masks all DAIF exceptions to keep things simple and avoid nested exceptions. With FEAT_NMI, that is no longer enough. Mask ALLINT as well to ensure things stay simple. Fixes: b3980e48528c ("arm64: kprobes: Recover pstate.D in single-step exception handler") Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com> Signed-off-by: Qinxin Xia <xiaqinxin@huawei.com> Signed-off-by: Hongye Lin <linhongye@h-partners.com> --- arch/arm64/include/asm/daifflags.h | 1 + arch/arm64/kernel/probes/kprobes.c | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h index 2417cc6b1631..bbb9e7da0e35 100644 --- a/arch/arm64/include/asm/daifflags.h +++ b/arch/arm64/include/asm/daifflags.h @@ -17,6 +17,7 @@ #define DAIF_PROCCTX_NOIRQ (PSR_I_BIT | PSR_F_BIT) #define DAIF_ERRCTX (PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) #define DAIF_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) +#define DAIF_ALLINT_MASK (system_uses_nmi() ? (PSR_ALLINT_BIT | DAIF_MASK) : DAIF_MASK) /* mask/save/unmask/restore all exceptions, including interrupts. */ diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index 70b91a8c6bb3..b2a0be8aa10d 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -184,16 +184,18 @@ static void __kprobes set_current_kprobe(struct kprobe *p) * the kprobe state is per-CPU and doesn't get migrated. */ static void __kprobes kprobes_save_local_irqflag(struct kprobe_ctlblk *kcb, - struct pt_regs *regs) + struct pt_regs *regs) { - kcb->saved_irqflag = regs->pstate & DAIF_MASK; - regs->pstate |= DAIF_MASK; + kcb->saved_irqflag = regs->pstate & DAIF_ALLINT_MASK; + + regs->pstate |= DAIF_ALLINT_MASK; } static void __kprobes kprobes_restore_local_irqflag(struct kprobe_ctlblk *kcb, - struct pt_regs *regs) + struct pt_regs *regs) { - regs->pstate &= ~DAIF_MASK; + regs->pstate &= ~DAIF_ALLINT_MASK; + regs->pstate |= kcb->saved_irqflag; } -- 2.33.0