18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci==========================
48c2ecf20Sopenharmony_ciThe Linux Microcode Loader
58c2ecf20Sopenharmony_ci==========================
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci:Authors: - Fenghua Yu <fenghua.yu@intel.com>
88c2ecf20Sopenharmony_ci          - Borislav Petkov <bp@suse.de>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ciThe kernel has a x86 microcode loading facility which is supposed to
118c2ecf20Sopenharmony_ciprovide microcode loading methods in the OS. Potential use cases are
128c2ecf20Sopenharmony_ciupdating the microcode on platforms beyond the OEM End-Of-Life support,
138c2ecf20Sopenharmony_ciand updating the microcode on long-running systems without rebooting.
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ciThe loader supports three loading methods:
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciEarly load microcode
188c2ecf20Sopenharmony_ci====================
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ciThe kernel can update microcode very early during boot. Loading
218c2ecf20Sopenharmony_cimicrocode early can fix CPU issues before they are observed during
228c2ecf20Sopenharmony_cikernel boot time.
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciThe microcode is stored in an initrd file. During boot, it is read from
258c2ecf20Sopenharmony_ciit and loaded into the CPU cores.
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ciThe format of the combined initrd image is microcode in (uncompressed)
288c2ecf20Sopenharmony_cicpio format followed by the (possibly compressed) initrd image. The
298c2ecf20Sopenharmony_ciloader parses the combined initrd image during boot.
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ciThe microcode files in cpio name space are:
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cion Intel:
348c2ecf20Sopenharmony_ci  kernel/x86/microcode/GenuineIntel.bin
358c2ecf20Sopenharmony_cion AMD  :
368c2ecf20Sopenharmony_ci  kernel/x86/microcode/AuthenticAMD.bin
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ciDuring BSP (BootStrapping Processor) boot (pre-SMP), the kernel
398c2ecf20Sopenharmony_ciscans the microcode file in the initrd. If microcode matching the
408c2ecf20Sopenharmony_ciCPU is found, it will be applied in the BSP and later on in all APs
418c2ecf20Sopenharmony_ci(Application Processors).
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciThe loader also saves the matching microcode for the CPU in memory.
448c2ecf20Sopenharmony_ciThus, the cached microcode patch is applied when CPUs resume from a
458c2ecf20Sopenharmony_cisleep state.
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ciHere's a crude example how to prepare an initrd with microcode (this is
488c2ecf20Sopenharmony_cinormally done automatically by the distribution, when recreating the
498c2ecf20Sopenharmony_ciinitrd, so you don't really have to do it yourself. It is documented
508c2ecf20Sopenharmony_cihere for future reference only).
518c2ecf20Sopenharmony_ci::
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci  #!/bin/bash
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci  if [ -z "$1" ]; then
568c2ecf20Sopenharmony_ci      echo "You need to supply an initrd file"
578c2ecf20Sopenharmony_ci      exit 1
588c2ecf20Sopenharmony_ci  fi
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci  INITRD="$1"
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci  DSTDIR=kernel/x86/microcode
638c2ecf20Sopenharmony_ci  TMPDIR=/tmp/initrd
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci  rm -rf $TMPDIR
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci  mkdir $TMPDIR
688c2ecf20Sopenharmony_ci  cd $TMPDIR
698c2ecf20Sopenharmony_ci  mkdir -p $DSTDIR
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci  if [ -d /lib/firmware/amd-ucode ]; then
728c2ecf20Sopenharmony_ci          cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin
738c2ecf20Sopenharmony_ci  fi
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci  if [ -d /lib/firmware/intel-ucode ]; then
768c2ecf20Sopenharmony_ci          cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin
778c2ecf20Sopenharmony_ci  fi
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci  find . | cpio -o -H newc >../ucode.cpio
808c2ecf20Sopenharmony_ci  cd ..
818c2ecf20Sopenharmony_ci  mv $INITRD $INITRD.orig
828c2ecf20Sopenharmony_ci  cat ucode.cpio $INITRD.orig > $INITRD
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci  rm -rf $TMPDIR
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ciThe system needs to have the microcode packages installed into
888c2ecf20Sopenharmony_ci/lib/firmware or you need to fixup the paths above if yours are
898c2ecf20Sopenharmony_cisomewhere else and/or you've downloaded them directly from the processor
908c2ecf20Sopenharmony_civendor's site.
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciLate loading
938c2ecf20Sopenharmony_ci============
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ciThere are two legacy user space interfaces to load microcode, either through
968c2ecf20Sopenharmony_ci/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file
978c2ecf20Sopenharmony_ciin sysfs.
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ciThe /dev/cpu/microcode method is deprecated because it needs a special
1008c2ecf20Sopenharmony_ciuserspace tool for that.
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ciThe easier method is simply installing the microcode packages your distro
1038c2ecf20Sopenharmony_cisupplies and running::
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci  # echo 1 > /sys/devices/system/cpu/microcode/reload
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cias root.
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ciThe loading mechanism looks for microcode blobs in
1108c2ecf20Sopenharmony_ci/lib/firmware/{intel-ucode,amd-ucode}. The default distro installation
1118c2ecf20Sopenharmony_cipackages already put them there.
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ciBuiltin microcode
1148c2ecf20Sopenharmony_ci=================
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ciThe loader supports also loading of a builtin microcode supplied through
1178c2ecf20Sopenharmony_cithe regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is
1188c2ecf20Sopenharmony_cicurrently supported.
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ciHere's an example::
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci  CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin"
1238c2ecf20Sopenharmony_ci  CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ciThis basically means, you have the following tree structure locally::
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci  /lib/firmware/
1288c2ecf20Sopenharmony_ci  |-- amd-ucode
1298c2ecf20Sopenharmony_ci  ...
1308c2ecf20Sopenharmony_ci  |   |-- microcode_amd_fam15h.bin
1318c2ecf20Sopenharmony_ci  ...
1328c2ecf20Sopenharmony_ci  |-- intel-ucode
1338c2ecf20Sopenharmony_ci  ...
1348c2ecf20Sopenharmony_ci  |   |-- 06-3a-09
1358c2ecf20Sopenharmony_ci  ...
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciso that the build system can find those files and integrate them into
1388c2ecf20Sopenharmony_cithe final kernel image. The early loader finds them and applies them.
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ciNeedless to say, this method is not the most flexible one because it
1418c2ecf20Sopenharmony_cirequires rebuilding the kernel each time updated microcode from the CPU
1428c2ecf20Sopenharmony_civendor is available.
143