^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) .. SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ==========================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) The Linux Microcode Loader
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) ==========================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) :Authors: - Fenghua Yu <fenghua.yu@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) - Borislav Petkov <bp@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) The kernel has a x86 microcode loading facility which is supposed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) provide microcode loading methods in the OS. Potential use cases are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) updating the microcode on platforms beyond the OEM End-Of-Life support,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) and updating the microcode on long-running systems without rebooting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) The loader supports three loading methods:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) Early load microcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) ====================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) The kernel can update microcode very early during boot. Loading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) microcode early can fix CPU issues before they are observed during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) kernel boot time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) The microcode is stored in an initrd file. During boot, it is read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) it and loaded into the CPU cores.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) The format of the combined initrd image is microcode in (uncompressed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) cpio format followed by the (possibly compressed) initrd image. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) loader parses the combined initrd image during boot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) The microcode files in cpio name space are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) on Intel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) kernel/x86/microcode/GenuineIntel.bin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) on AMD :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) kernel/x86/microcode/AuthenticAMD.bin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) During BSP (BootStrapping Processor) boot (pre-SMP), the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) scans the microcode file in the initrd. If microcode matching the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) CPU is found, it will be applied in the BSP and later on in all APs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) (Application Processors).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) The loader also saves the matching microcode for the CPU in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) Thus, the cached microcode patch is applied when CPUs resume from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) sleep state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) Here's a crude example how to prepare an initrd with microcode (this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) normally done automatically by the distribution, when recreating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) initrd, so you don't really have to do it yourself. It is documented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) here for future reference only).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #!/bin/bash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if [ -z "$1" ]; then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) echo "You need to supply an initrd file"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) exit 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) INITRD="$1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) DSTDIR=kernel/x86/microcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) TMPDIR=/tmp/initrd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) rm -rf $TMPDIR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mkdir $TMPDIR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) cd $TMPDIR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) mkdir -p $DSTDIR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if [ -d /lib/firmware/amd-ucode ]; then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if [ -d /lib/firmware/intel-ucode ]; then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) fi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) find . | cpio -o -H newc >../ucode.cpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) cd ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) mv $INITRD $INITRD.orig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) cat ucode.cpio $INITRD.orig > $INITRD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) rm -rf $TMPDIR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) The system needs to have the microcode packages installed into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /lib/firmware or you need to fixup the paths above if yours are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) somewhere else and/or you've downloaded them directly from the processor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) vendor's site.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) Late loading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) There are two legacy user space interfaces to load microcode, either through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) in sysfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) The /dev/cpu/microcode method is deprecated because it needs a special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) userspace tool for that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) The easier method is simply installing the microcode packages your distro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) supplies and running::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) # echo 1 > /sys/devices/system/cpu/microcode/reload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) as root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) The loading mechanism looks for microcode blobs in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /lib/firmware/{intel-ucode,amd-ucode}. The default distro installation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) packages already put them there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) Builtin microcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) =================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) The loader supports also loading of a builtin microcode supplied through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) currently supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) Here's an example::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) This basically means, you have the following tree structure locally::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /lib/firmware/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) |-- amd-ucode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) | |-- microcode_amd_fam15h.bin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) |-- intel-ucode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) | |-- 06-3a-09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) so that the build system can find those files and integrate them into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) the final kernel image. The early loader finds them and applies them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) Needless to say, this method is not the most flexible one because it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) requires rebuilding the kernel each time updated microcode from the CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) vendor is available.