Re: [PATCH RFC] arm64: entry: PSTATE_I_SET is leaking on pseudo NMI mode

From: Vladimir Murzin

Date: Tue Aug 11 2026 - 04:19:07 EST


On 8/11/26 03:47, Jinjie Ruan wrote:
>
> 在 2026/8/10 21:04, Vladimir Murzin 写道:
>> On 8/10/26 13:44, Jinjie Ruan wrote:
>>>> Agreed on the need for a clearer explanation.
>>>>
>>>> Perhaps local_irq_disable() isn't the right API here, and we should
>>>> use local_daif_restore(DAIF_PROCCTX_NOIRQ) instead?
>>> The local_irq_disable() here is pair with the local_irq_enable() in
>>> preempt_schedule_irq(). So I think it is not correct to replace them
>>> separately.
>>>
>>> The pseudo NMI does not consider how to do local_irq_disable() /enable()
>>> when the interrupt is masked by the DAIF.I bit as I reported before.
>> Unless I missed anything local_daif_restore(DAIF_PROCCTX_NOIRQ) would
>> clear DAIF.{IF} and set PMR to GIC_PRIO_IRQOFF which is the state we
> Hi, Vladimir,
>
> Yes, local_daif_restore(DAIF_PROCCTX_NOIRQ) does indeed clear the
> DAIF.IF bit and then set the PMR to IRQOFF.
>
> But there is a side effect that will clear the DAIF.{DA} bit. This will
> cause `arch_irqentry_exit_need_resched()` to bypass the DAIF check.
> Originally, it could not be preempted, but after this fix, it becomes
> preemptible.
>
> As the below comment said, If DAIF.{DA} is set, we may be handling an
> NMI or debug context, and preemption should not occur.
>

Yes, indeed, it is why in my other reply I added

"if we believe it is OK to downgrade the inherited context"

... and it seems it is not OK.

Cheers
Vladimir

> 30 static inline bool arch_irqentry_exit_need_resched(void)
> 31 {
> 32 >-------/*
> 33 >------- * DAIF.DA are cleared at the start of IRQ/FIQ handling, and
> when GIC
> 34 >------- * priority masking is used the GIC irqchip driver will
> clear DAIF.IF
> 35 >------- * using gic_arch_enable_irqs() for normal IRQs. If anything
> is set in
> 36 >------- * DAIF we must have handled an NMI, so skip preemption.
> 37 >------- */
> 38 >-------if (system_uses_irq_prio_masking() && read_sysreg(daif))
> 39 >------->-------return false;
>
> Best regards,
> Jinjie
>
>> expect from local_irq_disable() so we can do local_irq_{en,dis}able()
>> later on.
>>
>> Cheers
>> Vladimir
>>