| 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. |