SMM Architecture Overview
A practical overview of SMM, SMI handling, SMRAM/MMRAM, save state, lock timing, and firmware debug flow.
SMM, or System Management Mode, is a special CPU execution mode. When an SMI occurs, the CPU pauses the current context, saves register state, runs firmware code inside protected memory, and returns with RSM.
For debugging, it is better not to think of SMM as just a stronger interrupt handler. A more useful model is this: SMM is a firmware runtime island. It is built during boot, locked before the OS takes control, and can still be entered after the OS is running.
That makes SMM useful for variable services, flash protection, power events, thermal events, chipset policy, and OEM platform services. It also makes SMM failures difficult to read: the OS may only see a hang, reset, latency spike, failed SetVariable(), or a runtime command with no useful log.
Where SMM fits in the boot flow
SMM is not a linear phase like PEI, DXE, or BDS. PEI and DXE prepare memory, CPU state, the SMM Core, and SMM drivers. After that, SMM is locked and remains as a separate runtime environment.
A compact model:
PEI/DXE setup
-> reserve SMRAM/MMRAM
-> load SMM Core and SMM drivers
-> register SMI/SMM handlers
-> signal EndOfDxe / SmmReadyToLock
-> close and lock SMM resources
-> OS runtime can still trigger SMI
When debugging SMM, ask two separate questions: was the handler registered before the lock point, and can the dispatcher find it when the SMI arrives?
Basic SMI flow
A typical SMI path looks like this:
SMI source
-> CPU enters SMM
-> CPU saves register state
-> SMM Core runs inside SMRAM/MMRAM
-> dispatcher finds registered handler
-> handler validates input and handles request
-> handler clears source/status if needed
-> RSM returns to previous context
The source may be a software SMI, GPIO or chipset event, power event, thermal event, periodic SMI, or an SMM communication path. For software SMI, save state is often the clue that tells you the caller, command, and register context.
Main components
| Component | Role | Debug hint |
|---|---|---|
| SMI source | Why the CPU entered SMM | Check enable bits, status bits, and command IDs |
| Save State | Register snapshot before SMI | Useful for SW SMI, I/O trap, and exception debug |
| SMRAM/MMRAM | Private memory for SMM code and data | Never trust OS/DXE pointers without validation |
| SMM Core | Runtime core in Management Mode | Check load timing, dispatcher, handler database |
| SMM Handler | Code that handles the request or event | Validate buffer, size, command, and policy |
| SmmReadyToLock | Lock point for SMM setup | Late handler registration often fails after this point |
Important invariants
Keep these invariants in mind when reading SMM source:
- Code outside SMM must not modify SMRAM/MMRAM after lock.
- Handlers must not trust data provided by the OS or DXE runtime.
- Communication buffers need address, size, alignment, and overlap checks.
- Handlers should be short, bounded, and avoid Boot Services after
ExitBootServices(). - Dangerous debug or factory commands must be disabled or policy-gated before runtime.
If a handler trusts a pointer from a communication buffer without validation, that is not just a stability bug. It can be a security boundary failure.
Practical debug case
An OS tool calls a firmware service to write a setting. The tool only gets a generic error, and BIOS Setup does not show much. Do not start from the UI. Trace the path:
OS tool
-> Runtime Service or SMM Communication
-> CommBuffer validation
-> SW SMI or communication handler
-> SMM policy check
-> variable or flash backend
-> status returned to caller
If the handler never runs, check the SMI source, command ID, and registration timing. If it runs but returns an error, check buffer validation, policy lock state, variable attributes, flash locks, and SmmReadyToLock state.
What to look for in source
Start with these checks:
- Is the SMM driver built and placed in the right firmware volume?
- Is
MODULE_TYPEDXE_SMM_DRIVERor the equivalent in your codebase? - Is the handler registered in the entry point or after a notification event?
- Does registration happen before or after
SmmReadyToLock? - Which helper validates the communication buffer?
- Does validation reject overlap with SMRAM/MMRAM?
- Is the SMI source or status cleared correctly?
- Are debug and factory commands disabled before runtime?
Logs worth keeping
For SMM debug, sparse logs often hide the real timing issue. Log at least:
- SMM driver entry point
- handler registration status
- SMI command, source, and status
- communication buffer address and size
- validation result
- policy state: locked, unlocked, debug allowed, factory allowed
- backend status from variable, flash, or chipset access
- final return status
Avoid logging sensitive data such as keys, passwords, private variable payloads, or secure buffer contents.
SMM review checklist
Use this when reviewing or debugging an unstable SMM path.
Takeaway
SMM is not just an interrupt handler. It is a firmware runtime environment with its own memory, dispatcher, policy, and security boundary. When debugging, separate the trigger, handler registration, and policy/backend execution path.
Found this article useful?
Share it with someone learning firmware, BIOS/UEFI, or embedded systems, or support the author.
Nội dung liên quan
Một số bài viết, ghi chú hoặc project có liên quan đến nội dung bạn vừa đọc.
What Is the Runtime Phase?
Explains the UEFI Runtime Phase: the firmware parts that still matter after the OS takes control.
What is a System Management Interrupt (SMI)?
A System Management Interrupt enters SMM and runs firmware handlers. Understanding SMI helps debug latency spikes, SMI storms, and SMM communication failures.
What is System Management Mode (SMM)?
System Management Mode is a special firmware CPU mode outside normal OS control. Understanding SMM helps debug hangs, flash failures, and security bugs.
Biến note thành bài viết hoàn chỉnh
Notes là nơi ghi nhanh khái niệm.