Sunday 15 December 2013

Detecting System Management Interrupts

System Management Mode (SMM) is a special operating mode on x86 processors that temporarily jumps from normal execution and executes specialised firmware code in a high privilege before returning back.  SMM is entered via the System Management Interrupt (SMI) and is intented to work transparently to the operating system.

For example, SMM can be used to handle shutdown if CPU temperature is too high, perform transparent fan control, handle special system events (e.g. chipset errors), emulate hardware (non existing or buggy hardware) and a lot more besides.

SMM in theory cannot be disabled by the operating system and have been known to interfere with the operating system even though is it meant to be transparent.  SMIs steal CPU cycles from the system - CPU state has to be stored and restored and there are side effects because of flushing out of the write back cache.  This CPU cycle stealing can impact real time behaviour and in the past it has been hard to determine how frequently SMIs occur and hence how much potential disruption they bring to a system.

When the CPU enters SMM the output pin SMIACT# is asserted (and all further memory cycles are redirected to a protected memory for SMM).  Hence one could use a logic analyser on SMIACT# to count SMIs.   An alternative is to have a non-interruptible thread on a CPU checking time skips by constantly monitoring the Time Stamp Counter (TSC) but this is a CPU expensive operation.

Fortunately, modern Intel CPUs (such as Ivybridge and Haswell) have a special SMI counter in a Model Specific Register. MSR_SMI_COUNT (0x00000034) is incremented when SMIs occur, allowing easy detection of SMIs.

As a quick test, I hacked up smistat that polls MSR_SMI_COUNT every second.  For example, pressing the backlight brightness keys on my Lenovo laptop bumps the counter and this is easy to see with smistat.   So this MSR provides some indication of the frequency of SMIs, however, it of course cannot  inform us how many CPU cycles are stolen in SMM.   Now that would be a very useful MSR to add to the next revision of the Intel silicon...

1 comment:

  1. The MSRs IA32_TSC_ADJUST and IA32_TIME_STAMP_COUNTER might be manipulable in SMM to hide/mask cycles lost to the SMM. I suppose you could still try to track the TSC against wall clock looking for discrepancies, but is the TSC oscillator stable enough?

    With the released snowden information showing how adept the NSA has become at developing software that is able to enter the SMM and operate from inside that protection, it's reasonable to expect others have. Being able to account for time spent in SMM might be important to someone.

    Incidentally, there are a few proof of concept SMM viruses.

    Also, you might find the turbostat program found in the kernel source under tools/power/x86/turbostat interesting. It queries and decodes many more of the newer Intel MSRs including the MSR_SMI_COUNT. I found the processor package and per-core power consumption details surprising.