Search code examples
windowskerneluefi

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


Starting from Windows 10 1809, OS generates lots of software SMIs.
We are running our real time application on separate processor core and each SMI generates unpredictable delay. Before 1809 it was always possible to disable SMIs in BIOS.
Call stack in Windows looks like:

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

SMI is generated by OUT instruction into port 0xb2. It is required to read UEFI variables from NVRAM. When BIOS is in legacy mode, there is no SMIs.

Is it possible to configure Windows, so it will not access UEFI variables using SMIs?


Solution

  • The short answer is NO, it is not possible to configure Windows to not generate SW SMIs on UEFI Variable accesses, because those SMIs are not generated by Windows. The SMIs are generated inside the firmware.

    All UEFI-aware OSes read/write UEFI variables via GetVariable() and SetVariable() services, which are part of Runtime Services exposed by a UEFI firmware to the OS via System Table - see UEFI Spec, section 8. The current implementation of Variable Services in most firmware is to process the actual Get/Set variable requests inside SMM, for security reasons.

    So it is the device's firmware that's responsible for generating SW SMIs, not the OS. However, the OS and some system services/applications absolutely need to work with UEFI variables as it is how a UEFI-aware OS is supposed to run on a UEFI firmware.