Jump to content

# Microcode

6 languages

- Deutsch
- Español
- Magyar
- 日本語
- Русский
- 中文（简体）

From ArchWiki

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. In virtual machines and containers, the microcode updates belongs on the host, not in the guest system.

## Installation

To acquire updated microcode, depending on the processor, install one of the following packages:

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

mkinitcpio and dracut generate combined initramfs files by default. The microcode will be loaded automatically at boot time. Booster does not support generating combined initramfs, see the needed boot loader configuration at #Microcode in a separate initramfs file.

## Loading microcode

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. Built-in microcode can be compiled into the kernel and then applied by the early loader.
2. Early loading updates the microcode very early during boot, before the initramfs stage, and is preferred over late loading. This is mandatory for CPUs with severe hardware bugs, like the Intel Haswell and Broadwell processor families.
3. Late loading (Which may be dangerous) updates the microcode after booting which could be too late since the CPU might have already tried to use a faulty instruction. Even if already using early loading, late loading can still be used to apply a newer microcode update without needing to reboot.

### Early loading

The kernel's early loader expects microcode update files in `/kernel/x86/microcode/GenuineIntel.bin` or `/kernel/x86/microcode/AuthenticAMD.bin` inside an uncompressed CPIO archive (initramfs image).

The early initramfs image can be combined with the main initramfs image into one file and passed as a single initramfs to the kernel (via the `initrd=` kernel command line option by your boot loader or when packed in a unified kernel image) or it can exist as a separate file in which case multiple `initrd=` kernel command line options need to be used. In both cases, the uncompressed CPIO archive with the microcode must be placed before the main initramfs.

Note that because of the wide variability in users' early-boot configuration, microcode updates may not be triggered automatically by Arch's default configuration.

#### Custom built 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

#### Microcode initramfs packed together with the main initramfs in one file

The uncompressed microcode CPIO can be prepended into the initramfs and used as a single initramfs file. This method is preferred over #Microcode in a separate initramfs file since no additional boot parameter configuration is necessary.

Tip: You can optionally add `boot/*-ucode.img` to NoExtract in `/etc/pacman.conf`, since the microcode files will be picked up directly from `/usr/lib/firmware/*-ucode/`.

##### mkinitcpio

For mkinitcpio to generate an initramfs file that includes microcode, make sure `microcode` is in the `HOOKS` array in `/etc/mkinitcpio.conf`.

If the `autodetect` hook precedes `microcode`, then only the microcode for the current CPU will be included. To include all CPU microcode files that can be found on the system, move the `microcode` hook before `autodetect` or remove the `autodetect` hook entirely.

When generating the initramfs, mkinitcpio will show:

    -> Early uncompressed CPIO image generation successful

You can verify the initramfs includes the microcode update files with lsinitcpio(1). E.g.:

    # lsinitcpio --early /boot/initramfs-linux.img | grep microcode

    kernel/x86/microcode/
    kernel/x86/microcode/AuthenticAMD.bin

##### dracut

For dracut, see dracut.conf(5) § DESCRIPTION.

#### Microcode in a separate initramfs file

Note: Early microcode updates must otherwise be enabled by adding `/boot/amd-ucode.img` or `/boot/intel-ucode.img` as the first initrd in the boot loader configuration file—before the normal initrd file. See below for instructions for common boot loaders.

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

##### GRUB

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

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

Alternatively, users that manage their GRUB configuration 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.

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

##### EFISTUB

Append two `initrd=` options:

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

##### rEFInd

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

Edit boot options in `/boot/refind_linux.conf` and add an `initrd=` option for the microcode image as the first `initrd` argument passed. Use either `initrd=boot\cpu_manufacturer-ucode.img` or `initrd=cpu_manufacturer-ucode.img` depending if the files in `/boot` are in the root of a separate partition.

The microcode is required to be the first initramfs declared for the boot options list. 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"

###### Manual boot stanzas

Users employing manual stanzas in `esp/EFI/refind/refind.conf` to define kernels should add the `initrd=` parameter with the proper path within the boot partition. This parameter is required as part of 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 boot loaders do not support multiple initrd images. Follow the #Microcode initramfs packed together with the main initramfs in one file method instead.

##### Limine

For Limine you will just need to add the path to the microcode through the `MODULE_PATH` option in your limine.conf file. Here is an example:

    limine.conf

    default_entry: 1
    timeout: 3

    /Arch
        comment: Arch Linux

        protocol: linux
        kernel_path: boot():/vmlinuz-linux
        kernel_cmdline: root=UUID=c0748521-eca9-4f38-989c-43811b6e39a1 rw loglevel=3
        module_path: boot():/cpu_manufacturer-ucode.img
        module_path: boot():/initramfs-linux.img

### Late loading

Warning: Late microcode loading is considered dangerous, using it on Linux 5.19 and later will taint the kernel.[1]

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/`. The microcode update files are provided by amd-ucode and intel-ucode, respectively.

Late loading requires the kernel to be built with `CONFIG_MICROCODE_LATE_LOADING=y`, which is not the case for Arch officially supported kernels at the moment. [2]

#### Late loading microcode updates

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.

## 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:'

One should see something similar to the following on every boot, indicating that microcode is updated very early on:

    kernel: microcode: Current revision: 0x00000012
    kernel: microcode: Updated early from: 0x0000000e

It is entirely possible, particularly with newer hardware, that there is no microcode update for the CPU.

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.

## Which CPUs accept microcode updates

Users may consult either Intel's repository or Gentoo's wiki on AMD at the following links to see if a particular model is supported:

- Gentoo:AMD microcode#Microcode firmware files.
- Intel's Github repository.

### Detecting available microcode update

For Intel, it is possible to find out if the `/usr/lib/firmware/intel-ucode/` contains microcode for the running CPU with iucode_tool(8).

1. Install intel-ucode and iucode-tool
2. Load the `cpuid` kernel module:

       # modprobe cpuid

3. Search it for your cpuid:

       $ iucode_tool -lS /usr/lib/firmware/intel-ucode/

4. If an update is available, it should show up below selected microcodes
5. 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`

For AMD, it can be done manually.

1. Find out family, model and stepping of the CPU. For example, by running the following command:

       # journalctl -k --grep='CPU0:'

   Look at the output part like `(family: 0x15, model: 0x10, stepping: 0x1)`.
2. Match the values accordingly with the list from amd-ucode README.
3. If matched, compare the current revision of running microcode with the listed `Patch` value.

Note: You can also use lscpu(1) or `/proc/cpuinfo` output to get family, model and stepping. But you will need to convert the values into hexadecimal.

## Disable microcode loader

In case an updated CPU microcode causes issues, you may want to temporary disable the microcode loader to allow successfully booting and downgrading the package. To disable the kernel's microcode loader, specify the `dis_ucode_ldr` kernel parameter.

## 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
- Intel, AMD, VIA & Freescale CPU Microcode Repositories
- CPUID dumps

Categories:

- CPU
- Security