Linux administrators have several different options and methods to update their Intel systems’ microcode. We discuss details about these methods and provide multiple examples to help you choose the best option for your environment.
The Linux command line examples in this article start with either the $
(dollar symbol) to indicate the command can be run as a normal, non-privileged user, or the #
(hash symbol) to indicate that the command must be run as a privileged user (root). Comments next to the example commands will start with a //
(double forward slash symbol).
Some of the uses of microcode updates (MCUs) are to mitigate potential CPU security vulnerabilities and improve system security. Many operating system (OS) vendors provide automatic MCUs. OS vendors distribute microcode update in a form of packages. The packages are signed with OS vendor identity to help ensure integrity and authority of origin of the MCU. You should follow the instructions provided by your OS vendor to install MCUs. To learn more, refer to the Guidance for System Administrators to Mitigate Transient Execution Side Channel Issues.
Before installing critical files from the internet, such files should pass checksum match and identity verification. Instructions provided here should not be used in a production setup, as use in a production setup could result in a system being unmaintainable at scale and more vulnerable than before.
The system can load MCUs from multiple points. Refer to the Microcode Update Guidance for more details on the following loading points:
By updating the BIOS to include a newer (or older) MCU, the system administrator can upgrade (or downgrade) the MCU that is loaded when the system boots. Loading the microcode package as early as possible during boot time (via FIT or Early BIOS) increases the potential to effectively apply the mitigations implemented in the microcode and helps prevent later BIOS issues (for example, BIOS Memory Reference Code). However, a BIOS update requires a reboot. Updating microcode through BIOS might be the only approach on certain systems. Check with your vendor for options available on your system.
Intel regularly publishes new microcode for its products to the Intel Microcode Repository in GitHub so any user can download it. Usually these updates are located under /lib/firmware directory. This directory contains microcodes for all available Intel CPUs, listed by CPU signature (Family-Model-Stepping). During boot, the OS looks into /lib/firmware/intel-ucode for a microcode associated with a given system CPU. To find which CPU signature is associated with your processor, follow the steps in the next sections.
Family-Model-Stepping is a processor signature that identifies the model and version of the processor, and is needed during the microcode installation process. The CPU signature has three fields (family, model, and stepping) separated by dashes (-) and is represented in a hexadecimal form. There are multiple ways you can determine a given processor’s Family-Model-Stepping in Linux:
cpuid
commandlscpu
commandThe following example demystifies Family-Model-Stepping by using the lscpu
instruction.
$ lscpu // look for Family/Model/Stepping CPU family: 6 Model: 85 Stepping: 4
$ printf "%x\n" 6 // output: 6 $ printf "%x\n" 85 // output: 55 $ printf "%x\n" 4 // output:4
In the above example, the system has the 06-55-04 (Family-Model-Stepping) CPUID signature.
There are multiple methods to load microcode. Some of them require system reboot, others don’t. Some of them can only be applied to upgrade the microcode, while others allow you to both downgrade and upgrade your current microcode. Some of them will work regardless of your Linux distribution, and some are distribution specific.
Early OS MCU requires a reboot for all features to go into effect. Early OS MCU allows you to both upgrade and downgrade your microcode as needed. However, the CPU may prevent loading an MCU with a Revision ID lower than what was loaded by BIOS. This section describes the steps for Early OS MCU in some popular distributions. Different distributions will follow different methods, so you should check with your OS vendor before proceeding.
Before going forward, we need to explain the role initramfs
plays during microcode installation. In a nutshell, initramfs is a files archive. The main job of the initramfs
is to mount the root filesystem during kernel boot. During boot time, the boot loader loads the initramfs
image and kernel into ramfs
memory. After that, the boot loader initiates the kernel, and the kernel looks for initramfs
. If found, the kernel will mount it as / and initiate the init program (first process of the computer system).
# mkdir -p /lib/firmware/intel-ucode
# rsync -av /lib/firmware/intel-ucode /lib/firmware/intel-ucode.bak
# wget <copied_link>
:# wget https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/raw/master/intel-ucode/06-03-02
# mv 06-03-02 /lib/firmware/intel-ucode # cd /lib/firmware/intel-ucode
# rm -fr /lib/firmware/intel-ucode/family-model-stepping // e.g. rm -fr 06-55-04
# cp family-model-stepping /lib/firmware/intel-ucode/ // e.g. cp 06-55-04 /lib/firmware/intel-ucode/
update-initramfs
(assuming the desired microcode is already under /lib/firmware/intel-ucode).
# update-initramfs -c -k $(uname -r) # reboot
# dpkg --list | grep linux-image
linux-image-<kernel version>
with one from the above list of currently installed kernels.# sudo apt-get remove linux-image-
initramfs
. Refer to the upstream kernel files from the Ubuntu* archives (sorted by the most recent build). Substitute linux-image-<kernel version>.deb with the one downloaded from this link.# apt install ./linux-image-.deb
# reboot
On Ubuntu you can also use the update-intel-microcode tool. Update-intel-microcode is a script that downloads the current microcode for Intel processors and installs it on the filesystem.
For Red Hat* or Fedora*, use the dracut
utility. If this tool is not available on your system, there are two ways to install it:
# yum install dracut
$ wget https://mirrors.edge.kernel.org/pub/linux/utils/boot/dracut/dracut-(latest_version).tar.gz $ tar xf dracut-(latest_version).tar.gz // e.g. tar xf dracut-050.tar.gz $ cd dracut-(latest_version) // cd dracut-050 $ make $ su # make install sbindir=/sbin sysconfdir=/etc
wget
and yum
install commands, as shown in the example below:
# wget https://harald.fedorapeople.org/downloads/dracut/dracut-029-15.git20130705.fc19/dracut-029-15.git20130705.fc19.x86_64.rpm # rpm -U dracut-029-15.git20130705.fc19.x86_64.rpm
Note: Depending on your system, you might need to install additional packages from the dracut homepage.
Once you have dracut
installed, use the steps below to install the microcode using dracut:
# mkdir /lib/firmware/intel-ucode # cd /lib/firmware/intel-ucode
# rsync -av /lib/firmware/intel-ucode /lib/firmware/intel-ucode.bak
# rm -fr /lib/firmware/intel-ucode/family-model-stepping // e.g. rm -fr 06-55-04
# cp family-model-stepping /lib/firmware/intel-ucode/ // e.g. cp 06-55-04 /lib/firmware/intel-ucode/
initramfs
for the currently running kernel:# dracut -f "initramfs-$(uname -r).img" $(uname -r) // -f to overwrite an existing image
initramfs
, rebuild it with the following command:# dracut -f -vvv
# reboot
The method described here works for upgrading microcode only. It will not work for downgrading microcode. This method is agnostic to your Linux distribution. Loading an MCU during OS runtime must be done with care. Loading an update during runtime may change the CPU behavior in ways that is incompatible with running software. Furthermore, some updates may not be fully effective when loaded during runtime. To make sure CPU features are working properly, the same update should be loaded on all cores.
Therefore, Intel recommends that the system should be quiesced to the maximum extent possible when loading an MCU during runtime.
# mkdir /lib/firmware/intel-ucode # cd /lib/firmware/intel-ucode
# rsync -av /lib/firmware/intel-ucode /lib/firmware/intel-ucode.bak
# rm -fr /lib/firmware/intel-ucode/family-model-stepping // e.g. rm -fr 06-55-04
# cp family-model-stepping /lib/firmware/intel-ucode/ // e.g. cp 06-55-04 /lib/firmware/intel-ucode/
echo 1 > /sys/devices/system/cpu/microcode/reload
#!/bin/bash for i in /sys/devices/system/cpu/cpu[0-9]*/microcode/reload ; do echo 1 2>/dev/null > "$i" || true done
To verify if a microcode update was loaded correctly, check the microcode version before and after updating your system. You can use any of the following ways to check the current version of your microcode:
$ dmesg | grep microcode [ 0.000000] microcode: microcode updated early to revision 0xd2, date = 2020-01-09 [ 3.200591] microcode: sig=0x906ed, pf=0x2, revision=0xd2 [ 3.207755] microcode: Microcode Update Driver: v2.2.
$ cat /proc/cpuinfo | grep microcode | sort | uniq microcode : 0xd2
iucode_tool
can be used by any Linux distro. Refer to the instructions for how to download and install this tool. iucode_tool
scans your system and looks for information about your CPU signature. The value you are looking for is the output column that starts with rev (in bold below). In this example, 06-9e-0d is the signature of the processor currently running on the system.
$ iucode_tool -l /lib/firmware/intel-ucode/06-9e-0d selected microcodes: 001: sig 0x000906ed, pf mask 0x22, 2020-01-09, rev 0x00d2, size 102400
od
command. This command will display a long output, with the value that contains the microcode version in the third column of the first line of that output (000000d2
in the example below). We query the file 06-9e-0d, located in the folder in which we run the od
command.
$ od -t x4 /lib/firmware/intel-ucode/06-9e-0d 0000000 00000001 000000d2 01092020 000906ed