Microcode update is used to correct errata by loading an Intel-supplied data block (so-called microcode) into the processor. Especially, late microcode update (aka, load microcode to processors at run-time) avoids system reboot which is necessary in early microcode update and greatly reduces system downtime. But, current late microcode update on Xen may fail in some cases as microcode becomes more complex in order to fix some sophisticated security issues. Chao will introduce his work to improve reliability and efficiency of microcode update.
3. Background & Motivation
● Updating microcode is a MUST to mitigate recent vulnerabilities.
o e.g. L1TF & MDS
● Customers require an efficient and reliable way to update microcode
● We are striving to enhance existing microcode loading implementation
4. Microcode Update On Intel Platform
● An Intel-supplied data block
○ Used to correct errata in the processor
○ P6 family and later processors can load microcode update.
● Comprised of a descriptive header and encrypted update data
o Specify a list of processor signatures
o Revision number for authentication and verification
5. Steps To Load A Microcode Update On One CPU
1. Perform a checksum of the given microcode update
2. Get target CPU signature with CPUID [eax=1] and go through the header
and extended signature header to check whether current processor is
covered by the update
3. Read MSR IA32_BIOS_SIGN_ID to get current update revision and check
whether the microcode update is newer
4. Store the base address of encrypted data to EDX:EAX and write MSR
IA32_BIOS_UPDT_TRIG to trigger microcode loading
5. Read MSR IA32_BIOS_SIGN_ID again to check whether loading update
succeeds or not
6. ● During system initialization
○ Long downtime: reboot required
● During kernel bootup (a.k.a early microcode loading)
○ Long downtime: reboot required
● At run-time (a.k.a late microcode loading)
○ Negligible downtime: no reboot
3 Methods To Load A Microcode Update
7. Microcode Loading Support In Xen
● Early loading
○ For legacy boot: ucode=[<integer>|scan]
○ For EFI boot: ucode=<path_to_ucode>
● Check the output of “xl dmesg” to determine whether the processors get
updated
● Late loading
○ an hypercall, platform_op, XENPF_microcode_update
○ Lack of user-space tool
8. Current Implementation in Xen
● CPUs run without any control
● Repetitive parsing the same blob
● Interrupt would impact the process
● The whole process is serialized
9. Challenges Of Late Microcode Loading
● Interactions between workload on CPU and microcode update
○ Workload may interactive with features to be patched by microcode
update
● Various changes can be done by microcode update
○ Change the behavior of existing instructions
○ Introduce software-visible features (e.g. new MSR)
● Events may interrupt CPUs
○ External interrupts, #NMI, #MC
● There might be hundreds of CPUs to be updated
○ Downtime would increase
○ System unstable if interrupt is disabled for a long time
10. How To Deal With These Challenges
● Rendezvous all CPUs inside stop machine context
○ Only do what is necessary
○ Block #NMI handling
● Minimize the duration of microcode loading
○ Done parsing blob before rendezvous
○ Update microcode in parallel
11. Our Improvements
● Parsing blob is done once
● Limited CPU activities
● Interrupt disabled. #NMI handling
Blocked
● Microcode update in parallel
12. Other Improvements
● A tool to load microcode at runtime
○ tools/misc/xen-ucode <path to the microcode blob>
○ Hypercall interface remains the same.
● Reduced complexity
○ Not intended to support mixed processor steppings (or model)
○ Clean up the per-cpu microcode cache
13. Future Work
● Microcode revision in Dom0’s POV gets stale after late loading
○ Possible solution: re-read update revisions and enumerate related CPU
features in Dom0 kernel