|  | The Linux Microcode Loader | 
|  |  | 
|  | Authors: Fenghua Yu <fenghua.yu@intel.com> | 
|  | Borislav Petkov <bp@suse.de> | 
|  |  | 
|  | The kernel has a x86 microcode loading facility which is supposed to | 
|  | provide microcode loading methods in the OS. Potential use cases are | 
|  | updating the microcode on platforms beyond the OEM End-Of-Life support, | 
|  | and updating the microcode on long-running systems without rebooting. | 
|  |  | 
|  | The loader supports three loading methods: | 
|  |  | 
|  | 1. Early load microcode | 
|  | ======================= | 
|  |  | 
|  | The kernel can update microcode very early during boot. Loading | 
|  | microcode early can fix CPU issues before they are observed during | 
|  | kernel boot time. | 
|  |  | 
|  | The microcode is stored in an initrd file. During boot, it is read from | 
|  | it and loaded into the CPU cores. | 
|  |  | 
|  | The format of the combined initrd image is microcode in (uncompressed) | 
|  | cpio format followed by the (possibly compressed) initrd image. The | 
|  | loader parses the combined initrd image during boot. | 
|  |  | 
|  | The microcode files in cpio name space are: | 
|  |  | 
|  | on Intel: kernel/x86/microcode/GenuineIntel.bin | 
|  | on AMD  : kernel/x86/microcode/AuthenticAMD.bin | 
|  |  | 
|  | During BSP (BootStrapping Processor) boot (pre-SMP), the kernel | 
|  | scans the microcode file in the initrd. If microcode matching the | 
|  | CPU is found, it will be applied in the BSP and later on in all APs | 
|  | (Application Processors). | 
|  |  | 
|  | The loader also saves the matching microcode for the CPU in memory. | 
|  | Thus, the cached microcode patch is applied when CPUs resume from a | 
|  | sleep state. | 
|  |  | 
|  | Here's a crude example how to prepare an initrd with microcode (this is | 
|  | normally done automatically by the distribution, when recreating the | 
|  | initrd, so you don't really have to do it yourself. It is documented | 
|  | here for future reference only). | 
|  |  | 
|  | --- | 
|  | #!/bin/bash | 
|  |  | 
|  | if [ -z "$1" ]; then | 
|  | echo "You need to supply an initrd file" | 
|  | exit 1 | 
|  | fi | 
|  |  | 
|  | INITRD="$1" | 
|  |  | 
|  | DSTDIR=kernel/x86/microcode | 
|  | TMPDIR=/tmp/initrd | 
|  |  | 
|  | rm -rf $TMPDIR | 
|  |  | 
|  | mkdir $TMPDIR | 
|  | cd $TMPDIR | 
|  | mkdir -p $DSTDIR | 
|  |  | 
|  | if [ -d /lib/firmware/amd-ucode ]; then | 
|  | cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin | 
|  | fi | 
|  |  | 
|  | if [ -d /lib/firmware/intel-ucode ]; then | 
|  | cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin | 
|  | fi | 
|  |  | 
|  | find . | cpio -o -H newc >../ucode.cpio | 
|  | cd .. | 
|  | mv $INITRD $INITRD.orig | 
|  | cat ucode.cpio $INITRD.orig > $INITRD | 
|  |  | 
|  | rm -rf $TMPDIR | 
|  | --- | 
|  |  | 
|  | The system needs to have the microcode packages installed into | 
|  | /lib/firmware or you need to fixup the paths above if yours are | 
|  | somewhere else and/or you've downloaded them directly from the processor | 
|  | vendor's site. | 
|  |  | 
|  | 2. Late loading | 
|  | =============== | 
|  |  | 
|  | There are two legacy user space interfaces to load microcode, either through | 
|  | /dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file | 
|  | in sysfs. | 
|  |  | 
|  | The /dev/cpu/microcode method is deprecated because it needs a special | 
|  | userspace tool for that. | 
|  |  | 
|  | The easier method is simply installing the microcode packages your distro | 
|  | supplies and running: | 
|  |  | 
|  | # echo 1 > /sys/devices/system/cpu/microcode/reload | 
|  |  | 
|  | as root. | 
|  |  | 
|  | The loading mechanism looks for microcode blobs in | 
|  | /lib/firmware/{intel-ucode,amd-ucode}. The default distro installation | 
|  | packages already put them there. | 
|  |  | 
|  | 3. Builtin microcode | 
|  | ==================== | 
|  |  | 
|  | The loader supports also loading of a builtin microcode supplied through | 
|  | the regular firmware builtin method CONFIG_FIRMWARE_IN_KERNEL. Only | 
|  | 64-bit is currently supported. | 
|  |  | 
|  | Here's an example: | 
|  |  | 
|  | CONFIG_FIRMWARE_IN_KERNEL=y | 
|  | CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" | 
|  | CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" | 
|  |  | 
|  | This basically means, you have the following tree structure locally: | 
|  |  | 
|  | /lib/firmware/ | 
|  | |-- amd-ucode | 
|  | ... | 
|  | |   |-- microcode_amd_fam15h.bin | 
|  | ... | 
|  | |-- intel-ucode | 
|  | ... | 
|  | |   |-- 06-3a-09 | 
|  | ... | 
|  |  | 
|  | so that the build system can find those files and integrate them into | 
|  | the final kernel image. The early loader finds them and applies them. | 
|  |  | 
|  | Needless to say, this method is not the most flexible one because it | 
|  | requires rebuilding the kernel each time updated microcode from the CPU | 
|  | vendor is available. |