我们知道在ARM A-profile架构中(armv9.3之前)是不支持NMI中断的,但是操作系统对NMI类型中断又有强烈的需求,那都是怎么玩得呢? 如下便列举出,在ARM硬件上,操作系统层面做到了支持NMI的三种方式:
- 使用了 GIC 架构中的中断优先级特性。Linux 对特定中断号进行编程,使其其优先级高于所有其他中断。然后重写了arm64特定的中断启用和禁用函数来更改CPU中断优先级掩码(ICC_PMR_EL1),而不是直接操作CPU IRQ异常标志(PSTATE.I),从达到特定中断即可视为NMI。
- 利用gicv3/gicv4架构中的Group0中断特性,将需要置为NMI注册为SDEI中断,其实就是将该中断注册成group 0中断,该中断会target到EL3,EL3的handler函数再调用EL1注册时添加的回调函数。
- 如果是armv9.3及其之后的硬件,再配合gicv3.3及其之后的中断控制器,那么硬件上是可以支持NMI,此时软件不需要特殊处理,只需要使能这部分硬件即可。
补充有NMI需求的场景:
- watchdog
- 调试、跨 PE 同步和热补丁
- 操作系统依赖中断来支持性能分析
- RAS事件处理