【问题标题】:How to disable software SMI (System Management Interrupt) in Windows如何在 Windows 中禁用软件 SMI(系统管理中断)
【发布时间】:2020-04-19 03:55:09
【问题描述】:

从 Windows 10 1809 开始,操作系统会生成大量软件 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 变量?

【问题讨论】:

  • 我不认为你可以,因为它是 UEFI\BIOS 流程的一部分

标签: windows kernel uefi


【解决方案1】:

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

所有支持 UEFI 的操作系统都通过 GetVariable() 和 SetVariable() 服务读取/写入 UEFI 变量,这些服务是 UEFI 固件通过系统表向操作系统公开的运行时服务的一部分 - 请参阅 UEFI 规范第 8 节。出于安全原因,大多数固件中变量服务的实现是在 SMM 中处理实际的 Get/Set 变量请求。

因此,负责生成 SW SMI 的是设备的固件,而不是操作系统。但是,操作系统和某些系统服务/应用程序绝对需要使用 UEFI 变量,因为它是 UEFI 感知操作系统应该在 UEFI 固件上运行的方式。

【讨论】:

  • @prl,Windows 访问端口 0xb2。 固件输出到 0xb2 以响应 UEFI 变量访问。尽管 Ubuntu 和 Windows 都可以在没有变量的情况下启动,但我不会称它们为不必要的——很可能某些功能无法正常工作。 Windows 不会频繁访问 UEFI 变量;启动期间有大量读/写,但随后它会安静下来,只在必要时进行访问。我认为实际上不可能在 Windows 中禁用变量或阻止 0xb2 访问并保持其稳定。我会专注于找出谁可以访问系统中的变量。
  • @sun2sirius 感谢您的回答。很明显,SMM 是读取 UEFI 的唯一安全模式,但它是真正的性能下降。我知道操作系统可以在加载/关闭期间读取/写入 NVRAM,但为什么在运行时使用它?如果没有隐藏的注册表项,那么禁用 SMI 的唯一方法是在此类 API 调用上添加挂钩。
  • @vladimir-pustovalov,您可能想尝试向上调用堆栈,看看是谁在为 UEFI 变量进行内核调用。我刚刚构建了一个显示所有变量访问的测试 BIOS,并启动了 Windows——我在启动时看到了一次爆发,​​然后几分钟后又爆发了一次。但后来它再也没有发生过,我等了一个多小时。
  • 您还可以查看 GetEnvironmentVariable() 调用的堆栈帧以查看变量名称和 GUID - 这可能会让您了解访问它的原因。这绝对不正常。然后你可能能够找到读取变量的组件并看到它你可以更好地禁用或配置它。
【解决方案2】:

在支持 AMD-V 的处理器(例如 AMD 处理器、Hygon 处理器)上,答案是肯定的,但在内核模式下。有两条指令称为stgiclgi,其中stgi 设置GIFclgi 清除GIFGIF 用于控制中断行为,以便可以进入绝对原子操作。正如 AMD-V 中所定义的,Internal SMIs(例如 I/O 陷阱)被丢弃,External SMIs(例如来自外部硬件,或 APIC 的 IPI)在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

【讨论】:

    猜你喜欢
    • 2015-12-06
    • 2014-10-13
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 2018-09-09
    • 1970-01-01
    相关资源
    最近更新 更多