# Microcode

From ArchWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Processor manufacturers release stability and security updates to the processor microcode. These updates provide bug fixes that can be critical to the stability of your system. Without them, you may experience spurious crashes or unexpected system halts that can be difficult to track down.

All users with an AMD or Intel CPU should install the microcode updates to ensure system stability.

Microcode updates are usually shipped with the motherboard's firmware and applied during firmware initialization. Since OEMs might not release firmware updates in a timely fashion and old systems do not get new firmware updates at all, the ability to apply CPU microcode updates during boot was added to the Linux kernel. The Linux microcode loader supports three loading methods:

1. Early loading updates the microcode very early during boot, before the initramfs stage, so it is the preferred method. This is mandatory for CPUs with severe hardware bugs, like the Intel Haswell and Broadwell processor families.
2. Late loading updates the microcode after booting which could be too late since the CPU might have already tried to use a bugged instruction set. Even if already using early loading, late loading can still be used to apply a newer microcode update without needing to reboot.
3. Built-in microcode can be compiled into the kernel that is then applied by the early loader.

## Early loading

### Installation

Depending on the processor, install the following package:

- amd-ucode for AMD processors,
- intel-ucode for Intel processors.

Microcode must be loaded by the boot loader. Because of the wide variability in users' early-boot configuration, microcode updates may not be triggered automatically by Arch's default configuration. Many AUR kernels have followed the path of the official Arch kernels in this regard.

These updates must be enabled by adding `/boot/amd-ucode.img` or `/boot/intel-ucode.img` as the first initrd in the bootloader config file. This is before the normal initrd file. See below for instructions for common bootloaders.

In the following sections replace `cpu_manufacturer` with your CPU manufacturer, i.e. `amd` or `intel`.

Tip: For Arch Linux on a removable drive, which could be run on any of these processors, install both packages and add both microcode files as `initrd` to the boot loader configuration. Their order does not matter as long as they both are specified before the initramfs image.

### Configuration

#### Enabling early microcode loading in custom kernels

In order for early loading to work in custom kernels, "CPU microcode loading support" needs to be compiled into the kernel, not compiled as a module. This will enable the "Early load microcode" prompt which should be set to `Y`.

    CONFIG_BLK_DEV_INITRD=Y
    CONFIG_MICROCODE=y
    CONFIG_MICROCODE_INTEL=Y
    CONFIG_MICROCODE_AMD=y

#### GRUB

grub-mkconfig will automatically detect the microcode update and configure GRUB appropriately. After installing the microcode package, regenerate the GRUB config to activate loading the microcode update by running:

    # grub-mkconfig -o /boot/grub/grub.cfg

Note: grub-mkconfig does not add the microcode images to the fallback initramfs boot entry. See FS#60999.

Alternatively, users that manage their GRUB config file manually can add `/boot/cpu_manufacturer-ucode.img` (or `/cpu_manufacturer-ucode.img` if `/boot` is a separate partition) as follows:

    /boot/grub/grub.cfg

    ...
    echo 'Loading initial ramdisk'
    initrd	/boot/cpu_manufacturer-ucode.img /boot/initramfs-linux.img
    ...

Repeat it for each menu entry.

#### Dracut

This article or section needs language, wiki syntax or style improvements. See Help:Style for reference.

Reason: Placing the dracut section between two boot loader sections is confusing. (Discuss in Talk:Microcode#)

This article or section needs expansion.

Reason: Why should the initramfs be included in the initramfs? Will it load automatically without any boot loader configuration? This conflicts with the info in #Early loading. (Discuss in Talk:Microcode#)

When generating the initramfs with dracut the microcode should be included with the early-microcode step.

Check the output of this command to verify your system is configured correctly:

    # dracut --kver x.y.z-arch1-1 /boot/initramfs-linux.img

#### systemd-boot

Use the `initrd` option to load the microcode, before the initial ramdisk, as follows:

    /boot/loader/entries/entry.conf

    title   Arch Linux
    linux   /vmlinuz-linux
    initrd  /cpu_manufacturer-ucode.img
    initrd  /initramfs-linux.img
    ...

The latest microcode `cpu_manufacturer-ucode.img` must be available at boot time in your EFI system partition (ESP). The ESP must be mounted as `/boot` in order to have the microcode updated every time amd-ucode or intel-ucode is updated. Otherwise, copy `/boot/cpu_manufacturer-ucode.img` to your ESP at every update of the microcode package.

##### Unified kernel images

For unified kernel images, first generate the initrd to integrate by creating a new one as follows:

    $ cat /boot/cpu_manufacturer-ucode.img /boot/initramfs-linux.img > my_new_initrd.img
    $ objcopy ... --add-section .initrd=my_new_initrd .img

#### EFISTUB

Append two `initrd=` options:

    initrd=\cpu_manufacturer-ucode.img initrd=\initramfs-linux.img

#### rEFInd

Edit boot options in `/boot/refind_linux.conf` and add `initrd=boot\cpu_manufacturer-ucode.img` (or `initrd=cpu_manufacturer-ucode.img` if `/boot` is a separate partition) as the first initramfs. For example:

    "Boot using default options"     "root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw add_efi_memmap initrd=boot\cpu_manufacturer-ucode.img initrd=boot\initramfs-%v.img"

Tip: Users who previously did not specify an `initrd` kernel parameter will need to follow the steps described in rEFInd#Configuration to enable passing of multiple `initrd` parameters.

Users employing manual stanzas in `esp/EFI/refind/refind.conf` to define the kernels should simply add `initrd=boot\cpu_manufacturer-ucode.img` (or `initrd=cpu_manufacturer-ucode.img` if `/boot` is a separate partition) as required to the options line, and not in the main part of the stanza. E.g.:

    options  "root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw add_efi_memmap initrd=boot\cpu_manufacturer-ucode.img"

#### Syslinux

Note: There must be no spaces between the `cpu_manufacturer-ucode.img` and `initramfs-linux.img` initrd files. The `INITRD` line must be exactly as illustrated below.

Multiple initrd's can be separated by commas in `/boot/syslinux/syslinux.cfg`:

    LABEL arch
        MENU LABEL Arch Linux
        LINUX ../vmlinuz-linux
        INITRD ../cpu_manufacturer-ucode.img,../initramfs-linux.img
    ...

#### LILO

LILO and potentially other old bootloaders do not support multiple initrd images. In that case, `cpu_manufacturer-ucode.img` and `initramfs-linux.img` will have to be merged into one image.

Warning: The merged image must be recreated after each kernel update!
Note: The order is important. The original image `initramfs-linux.img` must be placed after `cpu_manufacturer-ucode.img` in the resulting image.

To merge both images into one image named `initramfs-merged.img`, the following command can be used:

    # cat /boot/cpu_manufacturer-ucode.img /boot/initramfs-linux.img > /boot/initramfs-merged.img

Now, edit `/etc/lilo.conf` to load the new image.

    ...
    initrd=/boot/initramfs-merged.img
    ...

And run `lilo` as root:

    # lilo

## Late loading

Late loading of microcode updates happens after the system has booted. It uses files in `/usr/lib/firmware/amd-ucode/` and `/usr/lib/firmware/intel-ucode/`.

For AMD processors the microcode update files are provided by linux-firmware.

For Intel processors no package provides the microcode update files (FS#59841). To use late loading you need to manually extract `intel-ucode/` from Intel's provided archive.

### Enabling late microcode updates

Unlike early loading, late loading of microcode updates on Arch Linux are enabled by default using `/usr/lib/tmpfiles.d/linux-firmware.conf`. After boot the file gets parsed by systemd-tmpfiles-setup.service(8) and CPU microcode gets updated.

To manually reload the microcode, e.g. after updating the microcode files in `/usr/lib/firmware/amd-ucode/` or `/usr/lib/firmware/intel-ucode/`, run:

    # echo 1 > /sys/devices/system/cpu/microcode/reload

This allows to apply newer microcode updates without rebooting the system. For linux-firmware you can automate it with a pacman hook, e.g.:

    /etc/pacman.d/hooks/microcode_reload.hook

    [Trigger]
    Operation = Upgrade
    Type = Path
    Target = usr/lib/firmware/amd-ucode/*

    [Action]
    Description = Applying CPU microcode updates...
    When = PostTransaction
    Depends = sh
    Exec = /bin/sh -c 'echo 1 > /sys/devices/system/cpu/microcode/reload'

### Disabling late microcode updates

For AMD systems the CPU microcode will get updated even if amd-ucode is not installed since the files in `/usr/lib/firmware/amd-ucode/` are provided by the linux-firmware package (FS#59840).

For virtual machines and containers (FS#46591) it is not possible to update the CPU microcode, so you may want to disable microcode updates. To do so, you must override the tmpfile `/usr/lib/tmpfiles.d/linux-firmware.conf` that is provided by linux-firmware. It can be done by creating a file with the same filename in `/etc/tmpfiles.d/`:

    # ln -s /dev/null /etc/tmpfiles.d/linux-firmware.conf

## Verifying that microcode got updated on boot

Check the kernel messages with journalctl to see if the microcode has been updated:

    # journalctl -k --grep=microcode

On Intel systems one should see something similar to the following on every boot, indicating that microcode is updated very early on:

    microcode: microcode updated early to revision 0xde, date = 2020-05-18
    microcode: sig=0x806ec, pf=0x80, revision=0xde
    microcode: Microcode Update Driver: v2.2.

Note: The date displayed does not correspond to the version of the intel-ucode package installed. It does show the last time Intel updated the microcode that corresponds to the specific hardware being updated.

It is entirely possible, particularly with newer hardware, that there is no microcode update for the CPU. In that case, the output may look like this:

    microcode: sig=0x806ec, pf=0x80, revision=0xde
    microcode: Microcode Update Driver: v2.2.

On AMD systems using early loading the output would look something like this:

    microcode: microcode updated early to new patch_level=0x0700010f
    microcode: CPU0: patch_level=0x0700010f
    microcode: CPU1: patch_level=0x0700010f
    microcode: CPU2: patch_level=0x0700010f
    microcode: CPU3: patch_level=0x0700010f
    microcode: Microcode Update Driver: v2.2.

On AMD systems using late loading the output will show the version of the old microcode before reloading the microcode and the new one once it is reloaded. It would look something like this:

    microcode: CPU0: patch_level=0x0700010b
    microcode: CPU1: patch_level=0x0700010b
    microcode: CPU2: patch_level=0x0700010b
    microcode: CPU3: patch_level=0x0700010b
    microcode: Microcode Update Driver: v2.2.
    microcode: CPU2: new patch_level=0x0700010f
    microcode: CPU0: new patch_level=0x0700010f
    microcode: CPU1: new patch_level=0x0700010f
    microcode: CPU3: new patch_level=0x0700010f
    x86/CPU: CPU features have changed after loading microcode, but might not take effect.

## Which CPUs accept microcode updates

Users may consult either Intel or AMD at the following links to see if a particular model is supported:

- AMD's Operating System Research Center[dead link 2019-07-01].
- Intel's download center.

### Detecting available microcode update

It is possible to find out if the `intel-ucode.img` contains a microcode image for the running CPU with iucode-tool.

1. Install intel-ucode (changing initrd is not required for detection)
2. Install iucode-tool
3. Load the `cpuid` kernel module:

       # modprobe cpuid

4. Extract microcode image and search it for your cpuid:

       # bsdtar -Oxf /boot/intel-ucode.img | iucode_tool -tb -lS -

5. If an update is available, it should show up below selected microcodes
6. The microcode might already be in your vendor bios and not show up loading in dmesg. Compare to the current microcode running `grep microcode /proc/cpuinfo`

## See also

- Updating microcodes – Experiences in the community
- Notes on Intel Microcode updates – Ben Hawkes
- Kernel microcode loader – kernel documentation
- Erratum found in Haswell/Broadwell – AnandTech
- iucode-tool GitLab project

Categories:

- CPU
- Security

Hidden categories:

- Pages or sections flagged with Template:Style
- Pages or sections flagged with Template:Expansion
- Pages with dead links