local_irq_disable函数其实是一个保险函数,具体含义为再执行依次CPU的中断关闭操作,给后续真正启动cpu的初始化铺路。
这个函数的展开位于/include/linux/irqflags.h文件中:
#define local_irq_disable() \
do { \
bool was_disabled = raw_irqs_disabled();\
raw_local_irq_disable(); \
if (!was_disabled) \
trace_hardirqs_off(); \
} while (0)这里主要涉及两个动作,第一是调用raw_local_irq_disable来关闭中断,第二是使用trace_hardirqs_off来判断是否完成关闭。
在irqflags.h头文件中,首先是将raw转为arch定义:

如上图,然后再在/arch/arm64/include/asm/irqflags.h中找到对应定义:
static inline void arch_local_irq_disable(void)
{
if (system_has_prio_mask_debugging()) {
u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF);
}
asm volatile(ALTERNATIVE(
"msr daifset, #2 // arch_local_irq_disable",
__msr_s(SYS_ICC_PMR_EL1, "%0"),
ARM64_HAS_IRQ_PRIO_MASKING)
:
: "r" ((unsigned long) GIC_PRIO_IRQOFF)
: "memory");
}可以看到,这里调用的是MSR指令写入daifset代表的寄存器完成中断关断。首先读SYS_ICC_PMR_EL1优先级掩码寄存器,然后根据掩码和ARM64_HAS_IRQ_PRIO_MASKING共同配置MSR写到DAIF寄存器,完成对应关断。DAIF寄存器描述如下:

理论上,DAIF寄存器是PSTATE寄存器的一部分,可以通过系统指令来访问其中的DAIF字段,对应为:
D:Debug表示位,0代表未屏蔽、1代表屏蔽,当开启时意味着屏蔽相关的中断
A:SError表示位,系统错误中断
I:IRQ表示位,普通中断请求掩码
F:FIQ表示位,快速中断请求掩码
使用MSR写命令最终把上述DAIF字段关了,就是完成中断关闭。