mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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.
 |