[RFC PATCH 07/36] arm64: entry: mask DAIF before returning from C EL1 handlers

Vladimir Murzin vladimir.murzin at arm.com
Tue Jul 14 03:13:04 PDT 2026


On 7/10/26 08:57, Jinjie Ruan wrote:
>> diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
>> index ceb4eb11232a..2be42d7f4eaa 100644
>> --- a/arch/arm64/kernel/entry-common.c
>> +++ b/arch/arm64/kernel/entry-common.c
>> @@ -495,6 +495,7 @@ static __always_inline void __el1_pnmi(struct pt_regs *regs,
>>  
>>  	state = irqentry_nmi_enter(regs);
>>  	do_interrupt_handler(regs, handler);
>> +	local_daif_mask();
>>  	irqentry_nmi_exit(regs, state);
>>  }
>>  
>> @@ -540,6 +541,7 @@ asmlinkage void noinstr el1h_64_error_handler(struct pt_regs *regs)
>>  	local_daif_restore(DAIF_ERRCTX);
>>  	state = irqentry_nmi_enter(regs);
>>  	do_serror(regs, esr);
>> +	local_daif_mask();
>>  	irqentry_nmi_exit(regs, state);
> This is similar to my patch below:
> 
> https://lore.kernel.org/all/20260703100135.2512312-4-ruanjinjie@huawei.com/
> 
> I think there are at least three problems:
> 
> 1、disable_daif is missing for el1h_64_sync_handler() and __el1_irq()

Hmm, here is call chain for el1h_64_sync_handler()

el1h_64_sync_handler()
  -> el1_abort()
     -> arm64_exit_to_kernel_mode()
        -> local_daif_mask()
  -> el1_pc()
     -> arm64_exit_to_kernel_mode()
        -> local_daif_mask()
  -> el1_undef()
     -> arm64_exit_to_kernel_mode()
        -> local_daif_mask()
  -> el1_bti()
     -> arm64_exit_to_kernel_mode()
        -> local_daif_mask()
  -> el1_gcs()
     -> arm64_exit_to_kernel_mode()
        -> local_daif_mask()
  -> el1_mops()
     -> arm64_exit_to_kernel_mode()
        -> local_daif_mask()
  -> el1_breakpt() /* Doesn't touch exceptions, so exception on exit are the same as on entry */
  -> el1_softstp() /* Ditto */
  -> el1_watchpt() /* Ditto */
  -> el1_brk64() /* Ditto*/
  -> el1_fpac() 
     -> arm64_exit_to_kernel_mode()
        -> local_daif_mask()

similarly for __el1_irq()

__el1_irq()
   -> arm64_exit_to_kernel_mode()
      -> local_daif_mask()

all them mask exceptions. What I'm missing?

> 
> 2、The order after moving to the C code is incorrect. disable_daif should
> be the exit point for C, that is, after irqentry_nmi_exit(), it is
> unclear why this order change occurred ?
> 

Fair point, I'll fix that in next iteration.

> 3、local_daif_mask () has added some pseudo NMI operations and
> trace_hardirqs_off ().

Yes, similarly we have for most exceptions. Could you, please, expand
on what is your concern with that?


Cheers
Vladimir



More information about the linux-arm-kernel mailing list