如何在 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 处理器),答案是肯定的,但在内核模式下。有两条指令称为 stgi
和 clgi
,其中 stgi
设置 GIF
,clgi
清除 GIF
。 GIF
用于控制中断行为,以便进入绝对原子操作。正如 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
从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 处理器),答案是肯定的,但在内核模式下。有两条指令称为 stgi
和 clgi
,其中 stgi
设置 GIF
,clgi
清除 GIF
。 GIF
用于控制中断行为,以便进入绝对原子操作。正如 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