如何在 Windows 中禁用软件 SMI(系统管理中断)

How to disable software SMI (System Management Interrupt) in Windows

从Windows10 1809开始,OS生成大量软件SMI。
我们是 运行 我们在单独处理器内核上的实时应用程序,每个 SMI 都会产生不可预测的延迟。在 1809 年之前,总是可以在 BIOS.
中禁用 SMI Windows 中的调用堆栈如下所示:

hal!HalEfiGetEnvironmentVariable+0x56       
hal!HalGetEnvironmentVariableEx+0xb572      
nt!IopGetEnvironmentVariableHal+0x2a        
nt!IoGetEnvironmentVariableEx+0x85          
nt!ExpGetFirmwareEnvironmentVariable+0x91   
nt!ExGetFirmwareEnvironmentVariable+0x110ce3
nt!NtQuerySystemEnvironmentValueEx+0x6e     

SMI 由 OUT 指令生成到端口 0xb2。需要从 NVRAM 读取 UEFI 变量。当 BIOS 处于传统模式时,没有 SMI。

是否可以配置 Windows,使其不会使用 SMI 访问 UEFI 变量?

简短的回答是否定的,无法将 Windows 配置为在 UEFI 变量访问时不生成 SW SMI,因为这些 SMI 不是由 Windows 生成的。 SMI 在固件内部生成。

通过 GetVariable() 和 SetVariable() 服务的所有 UEFI 感知 OSes read/write UEFI 变量,它们是 UEFI 固件向 OS 公开的运行时服务的一部分通过系统 Table - 请参阅 UEFI 规范第 8 节。出于安全原因,大多数固件中变量服务的当前实现是处理 SMM 内部的实际 Get/Set 变量请求。

因此,负责生成 SW SMI 的是设备固件,而不是 OS。然而,OS 和某些系统 services/applications 绝对需要使用 UEFI 变量,因为它是 UEFI 感知 OS 应该如何在 UEFI 固件上 运行。

在支持 AMD-V 的处理器上(例如 AMD 处理器、Hygon 处理器),答案是肯定的,但在内核模式下。有两条指令称为 stgiclgi,其中 stgi 设置 GIFclgi 清除 GIFGIF 用于控制中断行为,以便进入绝对原子操作。正如 AMD-V 中所定义的,当 GIF 是清除。确保在执行这些指令时启用 EFER MSR 中的 SVME 位。

如果您想以更通用的方式实现它,不依赖于 AMD-V,您可以尝试将您的代码放入 SMI 处理程序,因为稍后发生的 SMI 将在处理器时被锁存在SMM.

参考:
第 10.3.3 章“异常和中断”,第 2 卷“系统编程”,AMD64 体系结构程序员手册。
第 15.17 章“全局中断标志、STGI 和 CLGI 指令”,第 2 卷“系统编程”,AMD64 体系结构程序员手册。
https://www.amd.com/system/files/TechDocs/24593.pdf