AMD microcode

From Gentoo Wiki
Jump to:navigation Jump to:search

This article describes updating the microcode for AMD processors. In most cases the firmware of a system, i.e. the BIOS or UEFI, will contain updated processor microcode. It is recommended to always update the system firmware, because vendors will also incorporate new microcode provided by AMD with their BIOS updates (in the changelog this is often called "AGESA update"). It is however also possible to have the Linux kernel load the same updated microcode.

Important
For AMD GPU firmware see the corresponding articles radeon #Firmware and AMDGPU #Firmware instead.

Installation

Kernel configuration

For the Linux kernel to support CPU microcode loading, the following must be enabled if a kernel lower than version 6.6 is used. With kernel version 6.6 this is automatically activated and can no longer be selected [1] [2]:

KERNEL Enable AMD microcode loading support up to kernel version 6.5
Processor type and features  --->
    [*] CPU microcode loading support
    [ ]   Intel microcode loading support
    [*]   AMD microcode loading support

For the kernel to be able to load any firmware (including microcode), the firmware loading facility option must also be enabled:

KERNEL Enable firmware loading facility
Device Drivers  --->
    Generic Driver Options 
        Firmware loader --->
        {*} Firmware loading facility

When microcode is available and the kernel is configured, it will update microcode automatically. In most modern configurations the root partition (where the /lib/firmware directory is located) will be mounted during the boot process. For this reason, to be able to update the microcode as soon as possible, it is also necessary to include the microcode firmware blobs either in the kernel image or the initrd/initramfs.

Warning
Building the firmware loading facility as a module, {M} Firmware loading facility i.e. CONFIG_FW_LOADER=M, will prevent early microcode updating in most setups.

For further instructions, refer to the Microcode article.

Firmware blob files installation

Microcode updates for AMD processors are provided by the sys-kernel/linux-firmware package.

root #emerge --ask sys-kernel/linux-firmware

Microcode firmware files

There are different firmware files for different AMD CPU families. The CPU family identification of the current system can be obtained from /proc/cpuinfo:

user $grep -F -m 1 "cpu family" /proc/cpuinfo
cpu family      : 22

In this example the CPU belongs to the AMD CPU family 22.

Important
The CPU family identificator listed in /proc/cpuinfo uses the decimal numeral system.

The following table helps to identify the right firmware blob file for a given CPU family identificator:

Firmware blob file Decimal Hexadecimal Family name Year Examples
amd-ucode/microcode_amd.bin 16 10h K10 2007 Phenom, Phenom II, Athlon II
17 11h Turion 2008 Athlon X2, Sempron X2, Turion X2
18 12h Llano, Fusion 2009 A- and E2-Series APU with Radeon HD graphics, Athlon II, Sempron X2
20 14h Bobcat 2011 C- and E-Series APU with Radeon HD graphics
amd-ucode/microcode_amd_fam15h.bin 21 15h Bulldozer, Piledriver, Steamroller, Excavator 2011 FX series, A-Series APU with Radeon HD graphics, Opteron 6200/6300
amd-ucode/microcode_amd_fam16h.bin 22 16h Jaguar, Puma 2013 A-series and E-Series APU with Radeon HD graphics
amd-ucode/microcode_amd_fam17h.bin 23 17h Zen, Zen+, Zen 2 2017 Ryzen 1000-5000 series, Threadripper, EPYC 7xx1/7xx2
  amd/amd_sev_fam17h_model0xh.sbin EPYC 7xx1[3] (Zen 1) 2017 SEV (Secure Encrypted Virtualization) firmware update for models in the range 00h to 0fh[4]
  amd/amd_sev_fam17h_model3xh.sbin EPYC 7xx2[5] (Zen 2) 2019 SEV firmware update for models in the range 30h to 3fh[6]
amd-ucode/microcode_amd_fam19h.bin 25 19h Zen 3 and Zen 4 2021 Ryzen 5000 series (not all models), Ryzen 9 7900X & 7950X series, EPYC 7xx3
  amd/amd_sev_fam19h_model0xh.sbin EPYC 7xx3[7] (Zen 3) 2021 SEV firmware update for models in the range 00h to 0fh[8]
Note
Note that after the K8 AMD has started to refer to the various microarchitectures as "AMD Family xxh", where "xxh" is the hexadecimal CPU family value from the CPUID. For example, AMD Family 10h really is the official AMD name for the K10 microarchitecture. Following this convention AMD even used AMD Family 0Fh in retrospective for the previous K8 microarchitecture (CPUID 0F hexadecimal or 15 decimal).

Supplying the microcode files to the kernel

It is possible to incorporate the microcode firmware blob files for all AMD processors in the Linux kernel, but it should be considered that this will enlarge the kernel image by the combined size of those files.

KERNEL All AMD firmware blobs in-kernel
Device Drivers  --->
    Generic Driver Options 
        Firmware loader --->
        {*} Firmware loading facility
        (amd-ucode/microcode_amd.bin amd-ucode/microcode_amd_fam15h.bin amd-ucode/microcode_amd_fam16h.bin amd-ucode/microcode_amd_fam17h.bin amd/amd_sev_fam17h_model0xh.sbin amd/amd_sev_fam17h_model3xh.sbin amd-ucode/microcode_amd_fam19h.bin amd/amd_sev_fam19h_model0xh.sbin) External firmware blobs to build into the kernel binary
        (/lib/firmware) Firmware blobs root directory
Note
The CONFIG_EXTRA_FIRMWARE option allows specifying multiple firmware files by listing them space-separated.
The CONFIG_EXTRA_FIRMWARE_DIR is set to /lib/firmware, this is the default directory.

For in-kernel microcode it may be preferable to only include the firmware blob file(s) specific to the identified CPU. For example, for the EPYC 7xx1 CPU family this would be CONFIG_EXTRA_FIRMWARE="amd-ucode/microcode_amd_fam17h.bin amd/amd_sev_fam17h_model0xh.sbin".

Instead of in-kernel, the firmware blob files can also be included in an (additional) initrd/initramfs.

KERNEL Enable kernel support for loading microcode via initramfs/initrd
General setup  --- >
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support (BLK_DEV_INITRD)

This method has the advantage that only the specific initrd/initramfs must be rebuild in case of a firmware files update. If the initramfs USE flag is used with the sys-kernel/linux-firmware package, microcode for all AMD processors will be saved in /boot/amd-uc.img, allowing it to be loaded alongside any other initrd/initramfs by a Linux bootloader such as GRUB.

Note
With the initramfs USE flag set, package sys-kernel/linux-firmware will fail if /boot is a separate partition and is not mounted before installing or updating the package (by running emerge).
Note
GRUB will detect the presence of /boot/amd-uc.img and it will automatically be loaded. It may be necessary to update grub.cfg by running grub-mkconfig.

Verification

Booting a capable kernel, the following line should be observed in case a microcode update was performed: microcode: updated early

Note
It is possible the microcode has already been fully updated by the system's firmware vendor. In that case the dmesg output does not contain the update log message.

In any case the output will show a patch_level. The following example shows a successful early microcode update using the Linux kernel and supplied microcode firmware blob files (in-kernel or from an initrd/initramfs):

user $dmesg | grep microcode
[    0.584603] microcode: microcode: updated early to new patch_level=0x06000832
[    0.868036] microcode: CPU0: patch_level=0x06000832
[    0.868116] microcode: CPU1: patch_level=0x06000832
[    0.868196] microcode: CPU2: patch_level=0x06000832
[    0.868277] microcode: CPU3: patch_level=0x06000832
[    0.868360] microcode: CPU4: patch_level=0x06000832
[    0.868451] microcode: CPU5: patch_level=0x06000832
[    0.868538] microcode: CPU6: patch_level=0x06000832
[    0.868619] microcode: CPU7: patch_level=0x06000832
[    0.868718] microcode: Microcode Update Driver: v2.01 <tigran@aivazian.fsnet.co.uk>, Peter Oruba

Troubleshooting

Newly installed firmware is not used after a reboot

The image file /boot/amd-uc.img is in a file path recognized by GRUB by default, but only after regenerating the grub configuration. This is done by the following command:

root #grub-mkconfig -o /boot/grub/grub.cfg
Found linux image: /boot/vmlinuz-4.18.12
Found initrd image: /boot/amd-uc.img /boot/initramfs-4.18.12.img

The command output should show it found the /boot/amd-uc.img file.

After installing updated microcode firmware files, the kernel still loads the previous microcode patch-level

After updating sys-kernel/linux-firmware that includes updated AMD processor microcode they will only be installed to /lib/firmware on the root directory. With the initramfs USE flag set the package will also update /boot/amd-uc.img with the new firmware files, whereas (if so configured) both the main initramfs/initrd as well as the kernel will still contain the previous files from sys-kernel/linux-firmware.

If the microcode was supplied in-kernel, rebuilding and installing the kernel as usual is needed to finally provide the new microcode firmware files to the kernel during the boot process. Likewise, if the microcode was included in the main initramfs/initrd, rebuilding it will be necessary to replace the previous with the new versions of the microcode firmware files.

Note
Even after AMD releases updated microcode firmware files, it should be noted that it takes some time before they are included in sys-kernel/linux-firmware and maybe longer before they are supplied with the next stable version.

If the patch-level still doesn't change after including the updated firmware files it is very likely that the microcode simply doesn't apply for the specific CPU.

See also

References