xref: /linux/Documentation/arch/x86/microcode.rst (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
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