241 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3==========================4The Linux Microcode Loader5==========================6 7:Authors: - Fenghua Yu <fenghua.yu@intel.com>8 - Borislav Petkov <bp@suse.de>9 - Ashok Raj <ashok.raj@intel.com>10 11The kernel has a x86 microcode loading facility which is supposed to12provide microcode loading methods in the OS. Potential use cases are13updating the microcode on platforms beyond the OEM End-Of-Life support,14and updating the microcode on long-running systems without rebooting.15 16The loader supports three loading methods:17 18Early load microcode19====================20 21The kernel can update microcode very early during boot. Loading22microcode early can fix CPU issues before they are observed during23kernel boot time.24 25The microcode is stored in an initrd file. During boot, it is read from26it and loaded into the CPU cores.27 28The format of the combined initrd image is microcode in (uncompressed)29cpio format followed by the (possibly compressed) initrd image. The30loader parses the combined initrd image during boot.31 32The microcode files in cpio name space are:33 34on Intel:35 kernel/x86/microcode/GenuineIntel.bin36on AMD :37 kernel/x86/microcode/AuthenticAMD.bin38 39During BSP (BootStrapping Processor) boot (pre-SMP), the kernel40scans the microcode file in the initrd. If microcode matching the41CPU is found, it will be applied in the BSP and later on in all APs42(Application Processors).43 44The loader also saves the matching microcode for the CPU in memory.45Thus, the cached microcode patch is applied when CPUs resume from a46sleep state.47 48Here's a crude example how to prepare an initrd with microcode (this is49normally done automatically by the distribution, when recreating the50initrd, so you don't really have to do it yourself. It is documented51here for future reference only).52::53 54 #!/bin/bash55 56 if [ -z "$1" ]; then57 echo "You need to supply an initrd file"58 exit 159 fi60 61 INITRD="$1"62 63 DSTDIR=kernel/x86/microcode64 TMPDIR=/tmp/initrd65 66 rm -rf $TMPDIR67 68 mkdir $TMPDIR69 cd $TMPDIR70 mkdir -p $DSTDIR71 72 if [ -d /lib/firmware/amd-ucode ]; then73 cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin74 fi75 76 if [ -d /lib/firmware/intel-ucode ]; then77 cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin78 fi79 80 find . | cpio -o -H newc >../ucode.cpio81 cd ..82 mv $INITRD $INITRD.orig83 cat ucode.cpio $INITRD.orig > $INITRD84 85 rm -rf $TMPDIR86 87 88The system needs to have the microcode packages installed into89/lib/firmware or you need to fixup the paths above if yours are90somewhere else and/or you've downloaded them directly from the processor91vendor's site.92 93Late loading94============95 96You simply install the microcode packages your distro supplies and97run::98 99 # echo 1 > /sys/devices/system/cpu/microcode/reload100 101as root.102 103The loading mechanism looks for microcode blobs in104/lib/firmware/{intel-ucode,amd-ucode}. The default distro installation105packages already put them there.106 107Since kernel 5.19, late loading is not enabled by default.108 109The /dev/cpu/microcode method has been removed in 5.19.110 111Why is late loading dangerous?112==============================113 114Synchronizing all CPUs115----------------------116 117The microcode engine which receives the microcode update is shared118between the two logical threads in a SMT system. Therefore, when119the update is executed on one SMT thread of the core, the sibling120"automatically" gets the update.121 122Since the microcode can "simulate" MSRs too, while the microcode update123is in progress, those simulated MSRs transiently cease to exist. This124can result in unpredictable results if the SMT sibling thread happens to125be in the middle of an access to such an MSR. The usual observation is126that such MSR accesses cause #GPs to be raised to signal that former are127not present.128 129The disappearing MSRs are just one common issue which is being observed.130Any other instruction that's being patched and gets concurrently131executed by the other SMT sibling, can also result in similar,132unpredictable behavior.133 134To eliminate this case, a stop_machine()-based CPU synchronization was135introduced as a way to guarantee that all logical CPUs will not execute136any code but just wait in a spin loop, polling an atomic variable.137 138While this took care of device or external interrupts, IPIs including139LVT ones, such as CMCI etc, it cannot address other special interrupts140that can't be shut off. Those are Machine Check (#MC), System Management141(#SMI) and Non-Maskable interrupts (#NMI).142 143Machine Checks144--------------145 146Machine Checks (#MC) are non-maskable. There are two kinds of MCEs.147Fatal un-recoverable MCEs and recoverable MCEs. While un-recoverable148errors are fatal, recoverable errors can also happen in kernel context149are also treated as fatal by the kernel.150 151On certain Intel machines, MCEs are also broadcast to all threads in a152system. If one thread is in the middle of executing WRMSR, a MCE will be153taken at the end of the flow. Either way, they will wait for the thread154performing the wrmsr(0x79) to rendezvous in the MCE handler and shutdown155eventually if any of the threads in the system fail to check in to the156MCE rendezvous.157 158To be paranoid and get predictable behavior, the OS can choose to set159MCG_STATUS.MCIP. Since MCEs can be at most one in a system, if an160MCE was signaled, the above condition will promote to a system reset161automatically. OS can turn off MCIP at the end of the update for that162core.163 164System Management Interrupt165---------------------------166 167SMIs are also broadcast to all CPUs in the platform. Microcode update168requests exclusive access to the core before writing to MSR 0x79. So if169it does happen such that, one thread is in WRMSR flow, and the 2nd got170an SMI, that thread will be stopped in the first instruction in the SMI171handler.172 173Since the secondary thread is stopped in the first instruction in SMI,174there is very little chance that it would be in the middle of executing175an instruction being patched. Plus OS has no way to stop SMIs from176happening.177 178Non-Maskable Interrupts179-----------------------180 181When thread0 of a core is doing the microcode update, if thread1 is182pulled into NMI, that can cause unpredictable behavior due to the183reasons above.184 185OS can choose a variety of methods to avoid running into this situation.186 187 188Is the microcode suitable for late loading?189-------------------------------------------190 191Late loading is done when the system is fully operational and running192real workloads. Late loading behavior depends on what the base patch on193the CPU is before upgrading to the new patch.194 195This is true for Intel CPUs.196 197Consider, for example, a CPU has patch level 1 and the update is to198patch level 3.199 200Between patch1 and patch3, patch2 might have deprecated a software-visible201feature.202 203This is unacceptable if software is even potentially using that feature.204For instance, say MSR_X is no longer available after an update,205accessing that MSR will cause a #GP fault.206 207Basically there is no way to declare a new microcode update suitable208for late-loading. This is another one of the problems that caused late209loading to be not enabled by default.210 211Builtin microcode212=================213 214The loader supports also loading of a builtin microcode supplied through215the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is216currently supported.217 218Here's an example::219 220 CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin"221 CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"222 223This basically means, you have the following tree structure locally::224 225 /lib/firmware/226 |-- amd-ucode227 ...228 | |-- microcode_amd_fam15h.bin229 ...230 |-- intel-ucode231 ...232 | |-- 06-3a-09233 ...234 235so that the build system can find those files and integrate them into236the final kernel image. The early loader finds them and applies them.237 238Needless to say, this method is not the most flexible one because it239requires rebuilding the kernel each time updated microcode from the CPU240vendor is available.241