mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 01:10:04 +00:00
![Borislav Petkov](/assets/img/avatar_default.png)
Paul Menzel recently asked how to load microcode on a system and I realized that we don't really have all the methods written down somewhere. Do that, so people can go and look them up. Reported-by: Paul Menzel <pmenzel@molgen.mpg.de> Signed-off-by: Borislav Petkov <bp@suse.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20170724101228.17326-3-bp@alien8.de [ Fix whitespace noise in the new description. ] Signed-off-by: Ingo Molnar <mingo@kernel.org>
137 lines
3.9 KiB
Text
137 lines
3.9 KiB
Text
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.
|