1*ff61f079SJonathan Corbet.. SPDX-License-Identifier: GPL-2.0 2*ff61f079SJonathan Corbet 3*ff61f079SJonathan Corbet========================== 4*ff61f079SJonathan CorbetThe Linux Microcode Loader 5*ff61f079SJonathan Corbet========================== 6*ff61f079SJonathan Corbet 7*ff61f079SJonathan Corbet:Authors: - Fenghua Yu <fenghua.yu@intel.com> 8*ff61f079SJonathan Corbet - Borislav Petkov <bp@suse.de> 9*ff61f079SJonathan Corbet - Ashok Raj <ashok.raj@intel.com> 10*ff61f079SJonathan Corbet 11*ff61f079SJonathan CorbetThe kernel has a x86 microcode loading facility which is supposed to 12*ff61f079SJonathan Corbetprovide microcode loading methods in the OS. Potential use cases are 13*ff61f079SJonathan Corbetupdating the microcode on platforms beyond the OEM End-Of-Life support, 14*ff61f079SJonathan Corbetand updating the microcode on long-running systems without rebooting. 15*ff61f079SJonathan Corbet 16*ff61f079SJonathan CorbetThe loader supports three loading methods: 17*ff61f079SJonathan Corbet 18*ff61f079SJonathan CorbetEarly load microcode 19*ff61f079SJonathan Corbet==================== 20*ff61f079SJonathan Corbet 21*ff61f079SJonathan CorbetThe kernel can update microcode very early during boot. Loading 22*ff61f079SJonathan Corbetmicrocode early can fix CPU issues before they are observed during 23*ff61f079SJonathan Corbetkernel boot time. 24*ff61f079SJonathan Corbet 25*ff61f079SJonathan CorbetThe microcode is stored in an initrd file. During boot, it is read from 26*ff61f079SJonathan Corbetit and loaded into the CPU cores. 27*ff61f079SJonathan Corbet 28*ff61f079SJonathan CorbetThe format of the combined initrd image is microcode in (uncompressed) 29*ff61f079SJonathan Corbetcpio format followed by the (possibly compressed) initrd image. The 30*ff61f079SJonathan Corbetloader parses the combined initrd image during boot. 31*ff61f079SJonathan Corbet 32*ff61f079SJonathan CorbetThe microcode files in cpio name space are: 33*ff61f079SJonathan Corbet 34*ff61f079SJonathan Corbeton Intel: 35*ff61f079SJonathan Corbet kernel/x86/microcode/GenuineIntel.bin 36*ff61f079SJonathan Corbeton AMD : 37*ff61f079SJonathan Corbet kernel/x86/microcode/AuthenticAMD.bin 38*ff61f079SJonathan Corbet 39*ff61f079SJonathan CorbetDuring BSP (BootStrapping Processor) boot (pre-SMP), the kernel 40*ff61f079SJonathan Corbetscans the microcode file in the initrd. If microcode matching the 41*ff61f079SJonathan CorbetCPU is found, it will be applied in the BSP and later on in all APs 42*ff61f079SJonathan Corbet(Application Processors). 43*ff61f079SJonathan Corbet 44*ff61f079SJonathan CorbetThe loader also saves the matching microcode for the CPU in memory. 45*ff61f079SJonathan CorbetThus, the cached microcode patch is applied when CPUs resume from a 46*ff61f079SJonathan Corbetsleep state. 47*ff61f079SJonathan Corbet 48*ff61f079SJonathan CorbetHere's a crude example how to prepare an initrd with microcode (this is 49*ff61f079SJonathan Corbetnormally done automatically by the distribution, when recreating the 50*ff61f079SJonathan Corbetinitrd, so you don't really have to do it yourself. It is documented 51*ff61f079SJonathan Corbethere for future reference only). 52*ff61f079SJonathan Corbet:: 53*ff61f079SJonathan Corbet 54*ff61f079SJonathan Corbet #!/bin/bash 55*ff61f079SJonathan Corbet 56*ff61f079SJonathan Corbet if [ -z "$1" ]; then 57*ff61f079SJonathan Corbet echo "You need to supply an initrd file" 58*ff61f079SJonathan Corbet exit 1 59*ff61f079SJonathan Corbet fi 60*ff61f079SJonathan Corbet 61*ff61f079SJonathan Corbet INITRD="$1" 62*ff61f079SJonathan Corbet 63*ff61f079SJonathan Corbet DSTDIR=kernel/x86/microcode 64*ff61f079SJonathan Corbet TMPDIR=/tmp/initrd 65*ff61f079SJonathan Corbet 66*ff61f079SJonathan Corbet rm -rf $TMPDIR 67*ff61f079SJonathan Corbet 68*ff61f079SJonathan Corbet mkdir $TMPDIR 69*ff61f079SJonathan Corbet cd $TMPDIR 70*ff61f079SJonathan Corbet mkdir -p $DSTDIR 71*ff61f079SJonathan Corbet 72*ff61f079SJonathan Corbet if [ -d /lib/firmware/amd-ucode ]; then 73*ff61f079SJonathan Corbet cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin 74*ff61f079SJonathan Corbet fi 75*ff61f079SJonathan Corbet 76*ff61f079SJonathan Corbet if [ -d /lib/firmware/intel-ucode ]; then 77*ff61f079SJonathan Corbet cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin 78*ff61f079SJonathan Corbet fi 79*ff61f079SJonathan Corbet 80*ff61f079SJonathan Corbet find . | cpio -o -H newc >../ucode.cpio 81*ff61f079SJonathan Corbet cd .. 82*ff61f079SJonathan Corbet mv $INITRD $INITRD.orig 83*ff61f079SJonathan Corbet cat ucode.cpio $INITRD.orig > $INITRD 84*ff61f079SJonathan Corbet 85*ff61f079SJonathan Corbet rm -rf $TMPDIR 86*ff61f079SJonathan Corbet 87*ff61f079SJonathan Corbet 88*ff61f079SJonathan CorbetThe system needs to have the microcode packages installed into 89*ff61f079SJonathan Corbet/lib/firmware or you need to fixup the paths above if yours are 90*ff61f079SJonathan Corbetsomewhere else and/or you've downloaded them directly from the processor 91*ff61f079SJonathan Corbetvendor's site. 92*ff61f079SJonathan Corbet 93*ff61f079SJonathan CorbetLate loading 94*ff61f079SJonathan Corbet============ 95*ff61f079SJonathan Corbet 96*ff61f079SJonathan CorbetYou simply install the microcode packages your distro supplies and 97*ff61f079SJonathan Corbetrun:: 98*ff61f079SJonathan Corbet 99*ff61f079SJonathan Corbet # echo 1 > /sys/devices/system/cpu/microcode/reload 100*ff61f079SJonathan Corbet 101*ff61f079SJonathan Corbetas root. 102*ff61f079SJonathan Corbet 103*ff61f079SJonathan CorbetThe loading mechanism looks for microcode blobs in 104*ff61f079SJonathan Corbet/lib/firmware/{intel-ucode,amd-ucode}. The default distro installation 105*ff61f079SJonathan Corbetpackages already put them there. 106*ff61f079SJonathan Corbet 107*ff61f079SJonathan CorbetSince kernel 5.19, late loading is not enabled by default. 108*ff61f079SJonathan Corbet 109*ff61f079SJonathan CorbetThe /dev/cpu/microcode method has been removed in 5.19. 110*ff61f079SJonathan Corbet 111*ff61f079SJonathan CorbetWhy is late loading dangerous? 112*ff61f079SJonathan Corbet============================== 113*ff61f079SJonathan Corbet 114*ff61f079SJonathan CorbetSynchronizing all CPUs 115*ff61f079SJonathan Corbet---------------------- 116*ff61f079SJonathan Corbet 117*ff61f079SJonathan CorbetThe microcode engine which receives the microcode update is shared 118*ff61f079SJonathan Corbetbetween the two logical threads in a SMT system. Therefore, when 119*ff61f079SJonathan Corbetthe update is executed on one SMT thread of the core, the sibling 120*ff61f079SJonathan Corbet"automatically" gets the update. 121*ff61f079SJonathan Corbet 122*ff61f079SJonathan CorbetSince the microcode can "simulate" MSRs too, while the microcode update 123*ff61f079SJonathan Corbetis in progress, those simulated MSRs transiently cease to exist. This 124*ff61f079SJonathan Corbetcan result in unpredictable results if the SMT sibling thread happens to 125*ff61f079SJonathan Corbetbe in the middle of an access to such an MSR. The usual observation is 126*ff61f079SJonathan Corbetthat such MSR accesses cause #GPs to be raised to signal that former are 127*ff61f079SJonathan Corbetnot present. 128*ff61f079SJonathan Corbet 129*ff61f079SJonathan CorbetThe disappearing MSRs are just one common issue which is being observed. 130*ff61f079SJonathan CorbetAny other instruction that's being patched and gets concurrently 131*ff61f079SJonathan Corbetexecuted by the other SMT sibling, can also result in similar, 132*ff61f079SJonathan Corbetunpredictable behavior. 133*ff61f079SJonathan Corbet 134*ff61f079SJonathan CorbetTo eliminate this case, a stop_machine()-based CPU synchronization was 135*ff61f079SJonathan Corbetintroduced as a way to guarantee that all logical CPUs will not execute 136*ff61f079SJonathan Corbetany code but just wait in a spin loop, polling an atomic variable. 137*ff61f079SJonathan Corbet 138*ff61f079SJonathan CorbetWhile this took care of device or external interrupts, IPIs including 139*ff61f079SJonathan CorbetLVT ones, such as CMCI etc, it cannot address other special interrupts 140*ff61f079SJonathan Corbetthat can't be shut off. Those are Machine Check (#MC), System Management 141*ff61f079SJonathan Corbet(#SMI) and Non-Maskable interrupts (#NMI). 142*ff61f079SJonathan Corbet 143*ff61f079SJonathan CorbetMachine Checks 144*ff61f079SJonathan Corbet-------------- 145*ff61f079SJonathan Corbet 146*ff61f079SJonathan CorbetMachine Checks (#MC) are non-maskable. There are two kinds of MCEs. 147*ff61f079SJonathan CorbetFatal un-recoverable MCEs and recoverable MCEs. While un-recoverable 148*ff61f079SJonathan Corbeterrors are fatal, recoverable errors can also happen in kernel context 149*ff61f079SJonathan Corbetare also treated as fatal by the kernel. 150*ff61f079SJonathan Corbet 151*ff61f079SJonathan CorbetOn certain Intel machines, MCEs are also broadcast to all threads in a 152*ff61f079SJonathan Corbetsystem. If one thread is in the middle of executing WRMSR, a MCE will be 153*ff61f079SJonathan Corbettaken at the end of the flow. Either way, they will wait for the thread 154*ff61f079SJonathan Corbetperforming the wrmsr(0x79) to rendezvous in the MCE handler and shutdown 155*ff61f079SJonathan Corbeteventually if any of the threads in the system fail to check in to the 156*ff61f079SJonathan CorbetMCE rendezvous. 157*ff61f079SJonathan Corbet 158*ff61f079SJonathan CorbetTo be paranoid and get predictable behavior, the OS can choose to set 159*ff61f079SJonathan CorbetMCG_STATUS.MCIP. Since MCEs can be at most one in a system, if an 160*ff61f079SJonathan CorbetMCE was signaled, the above condition will promote to a system reset 161*ff61f079SJonathan Corbetautomatically. OS can turn off MCIP at the end of the update for that 162*ff61f079SJonathan Corbetcore. 163*ff61f079SJonathan Corbet 164*ff61f079SJonathan CorbetSystem Management Interrupt 165*ff61f079SJonathan Corbet--------------------------- 166*ff61f079SJonathan Corbet 167*ff61f079SJonathan CorbetSMIs are also broadcast to all CPUs in the platform. Microcode update 168*ff61f079SJonathan Corbetrequests exclusive access to the core before writing to MSR 0x79. So if 169*ff61f079SJonathan Corbetit does happen such that, one thread is in WRMSR flow, and the 2nd got 170*ff61f079SJonathan Corbetan SMI, that thread will be stopped in the first instruction in the SMI 171*ff61f079SJonathan Corbethandler. 172*ff61f079SJonathan Corbet 173*ff61f079SJonathan CorbetSince the secondary thread is stopped in the first instruction in SMI, 174*ff61f079SJonathan Corbetthere is very little chance that it would be in the middle of executing 175*ff61f079SJonathan Corbetan instruction being patched. Plus OS has no way to stop SMIs from 176*ff61f079SJonathan Corbethappening. 177*ff61f079SJonathan Corbet 178*ff61f079SJonathan CorbetNon-Maskable Interrupts 179*ff61f079SJonathan Corbet----------------------- 180*ff61f079SJonathan Corbet 181*ff61f079SJonathan CorbetWhen thread0 of a core is doing the microcode update, if thread1 is 182*ff61f079SJonathan Corbetpulled into NMI, that can cause unpredictable behavior due to the 183*ff61f079SJonathan Corbetreasons above. 184*ff61f079SJonathan Corbet 185*ff61f079SJonathan CorbetOS can choose a variety of methods to avoid running into this situation. 186*ff61f079SJonathan Corbet 187*ff61f079SJonathan Corbet 188*ff61f079SJonathan CorbetIs the microcode suitable for late loading? 189*ff61f079SJonathan Corbet------------------------------------------- 190*ff61f079SJonathan Corbet 191*ff61f079SJonathan CorbetLate loading is done when the system is fully operational and running 192*ff61f079SJonathan Corbetreal workloads. Late loading behavior depends on what the base patch on 193*ff61f079SJonathan Corbetthe CPU is before upgrading to the new patch. 194*ff61f079SJonathan Corbet 195*ff61f079SJonathan CorbetThis is true for Intel CPUs. 196*ff61f079SJonathan Corbet 197*ff61f079SJonathan CorbetConsider, for example, a CPU has patch level 1 and the update is to 198*ff61f079SJonathan Corbetpatch level 3. 199*ff61f079SJonathan Corbet 200*ff61f079SJonathan CorbetBetween patch1 and patch3, patch2 might have deprecated a software-visible 201*ff61f079SJonathan Corbetfeature. 202*ff61f079SJonathan Corbet 203*ff61f079SJonathan CorbetThis is unacceptable if software is even potentially using that feature. 204*ff61f079SJonathan CorbetFor instance, say MSR_X is no longer available after an update, 205*ff61f079SJonathan Corbetaccessing that MSR will cause a #GP fault. 206*ff61f079SJonathan Corbet 207*ff61f079SJonathan CorbetBasically there is no way to declare a new microcode update suitable 208*ff61f079SJonathan Corbetfor late-loading. This is another one of the problems that caused late 209*ff61f079SJonathan Corbetloading to be not enabled by default. 210*ff61f079SJonathan Corbet 211*ff61f079SJonathan CorbetBuiltin microcode 212*ff61f079SJonathan Corbet================= 213*ff61f079SJonathan Corbet 214*ff61f079SJonathan CorbetThe loader supports also loading of a builtin microcode supplied through 215*ff61f079SJonathan Corbetthe regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is 216*ff61f079SJonathan Corbetcurrently supported. 217*ff61f079SJonathan Corbet 218*ff61f079SJonathan CorbetHere's an example:: 219*ff61f079SJonathan Corbet 220*ff61f079SJonathan Corbet CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" 221*ff61f079SJonathan Corbet CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" 222*ff61f079SJonathan Corbet 223*ff61f079SJonathan CorbetThis basically means, you have the following tree structure locally:: 224*ff61f079SJonathan Corbet 225*ff61f079SJonathan Corbet /lib/firmware/ 226*ff61f079SJonathan Corbet |-- amd-ucode 227*ff61f079SJonathan Corbet ... 228*ff61f079SJonathan Corbet | |-- microcode_amd_fam15h.bin 229*ff61f079SJonathan Corbet ... 230*ff61f079SJonathan Corbet |-- intel-ucode 231*ff61f079SJonathan Corbet ... 232*ff61f079SJonathan Corbet | |-- 06-3a-09 233*ff61f079SJonathan Corbet ... 234*ff61f079SJonathan Corbet 235*ff61f079SJonathan Corbetso that the build system can find those files and integrate them into 236*ff61f079SJonathan Corbetthe final kernel image. The early loader finds them and applies them. 237*ff61f079SJonathan Corbet 238*ff61f079SJonathan CorbetNeedless to say, this method is not the most flexible one because it 239*ff61f079SJonathan Corbetrequires rebuilding the kernel each time updated microcode from the CPU 240*ff61f079SJonathan Corbetvendor is available. 241