AMD microcode

From Gentoo Wiki
Jump to: navigation, search

This article describes updating the microcode for AMD processors.

Note
For AMD GPU firmware see the corresponding GPU driver article instead.

Installation

Emerge

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

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

Kernel

In order to load the CPU microcode the following kernel options should be enabled:

KERNEL Generic AMD microcode support enablement
Processor type and features  --->
    [*] CPU microcode loading support
    [ ]   Intel microcode patch loading support
    [*]   AMD microcode patch loading support
Warning
Modules do not work for early microcode, so make sure microcode loading is built-in not a module.

Configuration

There are multiple ways how to update the microcode.

Built-in firmware

This way the firmware files will be built directly into the kernel.

Firmware blob files selection

You can either include all the available AMD firmware files to the kernel or select just the one specific for your CPU.

All firmware files

This setup simply builds all the firmware blobs into the kernel. This can be achieved by the following kernel optionsː

KERNEL All AMD firmware blobs
Device Drivers  --->
    Generic Driver Options 
        (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) External firmware blobs to build into the kernel binary
        (/lib/firmware) Firmware blobs root directory
Warning
Every option must be set as built into the kernel, not as a kernel module.
Note
The CONFIG_EXTRA_FIRMWARE option allows specifying multiple firmware files by listing them space-separated.
Specific firmware only

This way you only include the firmware suitable to your current CPU family. The CPU family identification 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.
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 is even using AMD Family 0Fh for the previous K8 microarchitecture (CPUID 0F hexadecimal or 15 decimal).

The following table helps to identify the right firmware blob file for 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
amd/amd_sev_fam17h_model0xh.sbin
23 17h Zen 2017 Ryzen 3|5|7, Threadripper, EPYC
AMD SEV (Secure Encrypted Virtualization) firmware update for AMD Family 17h models in the range 00h to 0fh[1]

The previously identified CPU specific firmware blob file (in this example CPU family 22) needs to be built into the kernelː

KERNEL Single AMD firmware blob
Device Drivers  --->
    Generic Driver Options 
        (amd-ucode/microcode_amd_fam16h.bin) External firmware blobs to build into the kernel binary
        (/lib/firmware) Firmware blobs root directory
Warning
Every option must be set as built into the kernel, not as a kernel module.

Initrd

You can load the microcode with the initrd.

Kernel

In order to use the initrd, you have to enable it in the kernel:

KERNEL Initrd support enablement
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

Firmware files preparation

First create the specified directory and cd into it. It doesn't have to be in /tmp but the kernel/x86/microcode part is necessary.

user $mkdir -p /tmp/amd-ucode/kernel/x86/microcode
user $cd /tmp/amd-ucode

Then we concatenate all the AMD firmware files into a single file. As before the path and filename of the output file must not be altered.

user $cat /lib/firmware/amd-ucode/microcode_amd*.bin > kernel/x86/microcode/AuthenticAMD.bin

Then we will create a cpio archive in /boot/amd-uc.img using bsdcpio from app-arch/libarchive:

root #echo kernel/x86/microcode/AuthenticAMD.bin | bsdcpio -o -H newc -R 0:0 > /boot/amd-uc.img

GRUB2 configuration

Since the image file /boot/amd-uc.img is one of the recognized ones by GRUB2 we just need to regenerate grub config.

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

It should show that it found the /boot/amd-uc.img file.

Building the kernel

Rebuild and install the kernel as usual.

Verification

After the next reboot with the new kernel, you should see a similar output:

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

The first line contains the microcode: updated early log message in case a microcode update was performed during the boot.

References

  1. [PATCH] linux-firmware: Update AMD SEV firmware (LKML, Josh Boyer, commit pushed, 18 Jun 2019)