Microcode: Difference between revisions

From ArchWiki
m (→‎LILO: Remove extra white space)
(Undo revision 805587 by Cvlc (talk) - intro is for intro, not instructions)
Tag: Undo
 
(77 intermediate revisions by 24 users not shown)
Line 6: Line 6:
[[ru:Microcode]]
[[ru:Microcode]]
[[zh-hans:Microcode]]
[[zh-hans:Microcode]]
{{Expansion|
* Needs to be updated to reflect that late loading on AMD is considered supported and [https://lore.kernel.org/lkml/20230411125056.2333-1-bp@alien8.de/ no longer taints the kernel].
* Changes for the [https://www.phoronix.com/news/Linux-6.7-x86-Microcode 6.7 release] of the kernel might also fit here.
* Hook migration to remove initrd now that [https://archlinux.org/news/mkinitcpio-hook-migration-and-early-microcode/ mkinitcpio can include microcode in initramfs].
}}
Processor manufacturers release stability and security updates to the processor [[Wikipedia:Microcode|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.
Processor manufacturers release stability and security updates to the processor [[Wikipedia:Microcode|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.
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.
 
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. [https://docs.kernel.org/x86/microcode.html The Linux microcode loader] supports three loading methods:


# '''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.
== Loading microcode ==
# '''Late loading''' ('''dangerous''') 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.
# '''Built-in microcode''' can be compiled into the kernel that is then applied by the early loader.


== Early loading ==
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. [https://docs.kernel.org/arch/x86/microcode.html The Linux microcode loader] supports three loading methods:


=== Installation ===
# '''Built-in microcode''' can be compiled into the kernel and then applied by the early loader.
# '''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.
# '''Late loading''' ([https://docs.kernel.org/arch/x86/microcode.html#why-is-late-loading-dangerous 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.


Depending on the processor, [[install]] the following package:
To acquire updated microcode, depending on the processor, [[install]] one of the following packages:
* {{Pkg|amd-ucode}} for AMD processors,
* {{Pkg|amd-ucode}} for AMD processors,
* {{Pkg|intel-ucode}} for Intel processors.
* {{Pkg|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.
=== Early loading ===


These updates must be enabled by adding {{ic|/boot/amd-ucode.img}} or {{ic|/boot/intel-ucode.img}} as the '''first initrd in the bootloader configuration file'''. This is before the normal initrd file. See below for instructions for common bootloaders.
If not compiled into the kernel, microcode must be loaded by the early loader.


In the following sections replace {{ic|''cpu_manufacturer''}} with your CPU manufacturer, i.e. {{ic|amd}} or {{ic|intel}}.
Early loader expects microcode update files in {{ic|/kernel/x86/microcode/GenuineIntel.bin}} or {{ic|/kernel/x86/microcode/AuthenticAMD.bin}} inside an uncompressed CPIO archive (initramfs image).


{{Tip|For [[Install Arch Linux on a removable medium|Arch Linux on a removable drive]], which could be run on any of these processors, install both packages and add both microcode files as {{ic|initrd}} to the boot loader configuration. Their order does not matter as long as they both are specified before the 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 {{ic|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 {{ic|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.


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


==== Enabling early microcode loading in custom kernels ====
==== 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 {{ic|Y}}.
In order for early loading to work in [[Kernel/Arch build system|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 {{ic|Y}}.


  CONFIG_BLK_DEV_INITRD=Y
  CONFIG_BLK_DEV_INITRD=Y
Line 43: Line 47:
  CONFIG_MICROCODE_AMD=y
  CONFIG_MICROCODE_AMD=y


==== GRUB ====
==== Microcode initramfs packed together with the main initramfs in one file ====
 
The uncompressed microcode CPIO can be [https://docs.kernel.org/arch/x86/microcode.html#early-load-microcode 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.
 
[[mkinitcpio]] and [[dracut]] support generating such combined initramfs files and do so by default. [[Booster]] [https://github.com/anatol/booster/issues/40 does not support generating combined initramfs].
 
===== mkinitcpio =====
 
For [[mkinitcpio]] to generate an initramfs file that includes microcode, make sure {{ic|microcode}} is in the {{ic|HOOKS}} array in {{ic|/etc/mkinitcpio.conf}}.
 
If the {{ic|autodetect}} hook precedes {{ic|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 {{ic|microcode}} hook before {{ic|autodetect}} or remove the {{ic|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 {{man|1|lsinitcpio}}. E.g.:
 
{{hc|# lsinitcpio --early /boot/initramfs-linux.img|
early_cpio
kernel/
kernel/x86/
kernel/x86/microcode/
kernel/x86/microcode/AuthenticAMD.bin
}}
 
===== dracut =====
 
For [[dracut]], see {{man|5|dracut.conf|DESCRIPTION}}.
 
==== Microcode in a separate initramfs file ====
 
Early microcode updates must otherwise be enabled by adding {{ic|/boot/amd-ucode.img}} or {{ic|/boot/intel-ucode.img}} as the '''first initrd in the bootloader configuration file'''. This is before the normal initrd file. See below for instructions for common bootloaders.
 
In the following sections replace {{ic|''cpu_manufacturer''}} with your CPU manufacturer, i.e. {{ic|amd}} or {{ic|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'' 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:
Line 60: Line 100:
Repeat it for each menu entry.
Repeat it for each menu entry.


==== systemd-boot ====
===== systemd-boot =====


Use the {{ic|initrd}} option to load the microcode, before the initial ramdisk, as follows:
Use the {{ic|initrd}} option to load the microcode, before the initial ramdisk, as follows:
Line 74: Line 114:
The latest microcode {{ic|''cpu_manufacturer''-ucode.img}} must be available at boot time in your [[EFI system partition]] (ESP). The ESP must be mounted as {{ic|/boot}} in order to have the microcode updated every time {{Pkg|amd-ucode}} or {{Pkg|intel-ucode}} is updated. Otherwise, copy {{ic|/boot/''cpu_manufacturer''-ucode.img}} to your ESP at every update of the microcode package.
The latest microcode {{ic|''cpu_manufacturer''-ucode.img}} must be available at boot time in your [[EFI system partition]] (ESP). The ESP must be mounted as {{ic|/boot}} in order to have the microcode updated every time {{Pkg|amd-ucode}} or {{Pkg|intel-ucode}} is updated. Otherwise, copy {{ic|/boot/''cpu_manufacturer''-ucode.img}} to your ESP at every update of the microcode package.


==== Unified kernel images ====
===== EFISTUB =====
 
See [[Unified kernel image#Manually]].
 
==== EFISTUB ====


Append two {{ic|1=initrd=}} options:
Append two {{ic|1=initrd=}} options:
Line 84: Line 120:
  '''initrd=\''cpu_manufacturer''-ucode.img''' initrd=\initramfs-linux.img
  '''initrd=\''cpu_manufacturer''-ucode.img''' initrd=\initramfs-linux.img


==== rEFInd ====
===== rEFInd =====


Edit boot options in {{ic|/boot/refind_linux.conf}} and add {{ic|1=initrd=boot\''cpu_manufacturer''-ucode.img}} (or {{ic|1=initrd=''cpu_manufacturer''-ucode.img}} if {{ic|/boot}} is a separate partition) as the first initramfs. For example:
{{Tip|Users who previously did not specify an {{ic|initrd}} kernel parameter need to follow the steps described in [[rEFInd#Configuration]] to enable the passing of multiple {{ic|initrd}} parameters.}}


"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"
Edit boot options in {{ic|/boot/refind_linux.conf}}
and add an {{ic|1=initrd=}} option for the microcode image as the first {{ic|initrd}} argument passed. Use either {{ic|1=initrd=boot\''cpu_manufacturer''-ucode.img}} or {{ic|1=initrd=''cpu_manufacturer''-ucode.img}} depending if the files in {{ic|/boot}} are in the root of a separate partition.


{{Tip|Users who previously did not specify an {{ic|initrd}} kernel parameter will need to follow the steps described in [[rEFInd#Configuration]] to enable passing of multiple {{ic|initrd}} parameters.}}
The microcode is required to be the first initramfs declared for the boot options list. For example:


Users employing [[rEFInd#For manual boot stanzas|manual stanzas]] in {{ic|''esp''/EFI/refind/refind.conf}} to define the kernels should simply add {{ic|1=initrd=boot\''cpu_manufacturer''-ucode.img}} (or {{ic|1=initrd=''cpu_manufacturer''-ucode.img}} if {{ic|/boot}} is a separate partition) as required to the options line, and not in the main part of the stanza. E.g.:
"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 [[rEFInd#For manual boot stanzas|manual stanzas]] in {{ic|''esp''/EFI/refind/refind.conf}} to define kernels should add the {{ic|1=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'''"
  options  "root=PARTUUID=''XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'' rw add_efi_memmap '''initrd=boot\''cpu_manufacturer''-ucode.img'''"


==== Syslinux ====
===== Syslinux =====


{{Note|There must be no spaces between the {{ic|''cpu_manufacturer''-ucode.img}} and {{ic|initramfs-linux.img}} initrd files. The {{ic|INITRD}} line must be exactly as illustrated below.}}
{{Note|There must be no spaces between the {{ic|''cpu_manufacturer''-ucode.img}} and {{ic|initramfs-linux.img}} initrd files. The {{ic|INITRD}} line must be exactly as illustrated below.}}
Line 108: Line 148:
  ...
  ...


==== LILO ====
===== LILO =====


[[LILO]] and potentially other old bootloaders do not support multiple initrd images. In that case, {{ic|''cpu_manufacturer''-ucode.img}} and {{ic|initramfs-linux.img}} will have to be merged into one image.
[[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.


{{Warning|The merged image must be recreated after each kernel update!}}
===== Limine =====


{{Note|The order is important. The original image {{ic|initramfs-linux.img}} must be placed '''after''' {{ic|''cpu_manufacturer''-ucode.img}} in the resulting image.}}
For [[Limine]] you will just need to add the path to the microcode through the {{ic|MODULE_PATH}} option in your [[Limine#Configuration|limine.cfg]] file. Here is an example:


To merge both images into one image named {{ic|initramfs-merged.img}}, the following command can be used:
{{hc|limine.cfg|2=
DEFAULT_ENTRY=1
TIMEOUT=3


# cat /boot/''cpu_manufacturer''-ucode.img /boot/initramfs-linux.img > /boot/initramfs-merged.img
:Arch
    COMMENT=Arch Linux


Now, edit {{ic|/etc/lilo.conf}} to load the new image.
    PROTOCOL=linux
    KERNEL_PATH=boot:///vmlinuz-linux
    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 ===
initrd=/boot/initramfs-merged.img
...
 
And run {{ic|lilo}} as root:
 
# lilo
 
== Late loading ==
 
{{Warning|1=Late microcode loading is considered dangerous, using it on Linux 5.19 will taint the kernel.[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9784edd73a08ea08d0ce5606e1f0f729df688c59]}}
 
Late loading of microcode updates happens after the system has booted. It uses files in {{ic|/usr/lib/firmware/amd-ucode/}} and {{ic|/usr/lib/firmware/intel-ucode/}}. On Linux 5.19+ late loading requires the kernel to be built with {{ic|1=CONFIG_MICROCODE_LATE_LOADING=y}}.


For AMD processors the microcode update files are provided by {{Pkg|linux-firmware}}.
{{Warning|1=Late microcode loading is considered dangerous, using it on Linux 5.19 and later will taint the kernel.[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9784edd73a08ea08d0ce5606e1f0f729df688c59]}}


For Intel processors no package provides the microcode update files ({{Bug|59841}}). To use late loading you need to manually extract {{ic|intel-ucode/}} from [https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases Intel's provided archive].
Late loading of microcode updates happens after the system has booted. It uses files in {{ic|/usr/lib/firmware/amd-ucode/}} and {{ic|/usr/lib/firmware/intel-ucode/}}. The microcode update files are provided by {{Pkg|amd-ucode}} and {{Pkg|intel-ucode}}, respectively.


=== Enabling late microcode updates ===
Late loading requires the kernel to be built with {{ic|1=CONFIG_MICROCODE_LATE_LOADING=y}}, which is not the case for Arch [[Kernel#Officially supported kernels|officially supported kernels]] at the moment. [https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/blob/8d50b29ca6b927096ecf678cec193fc230b447cd/config#L462]


Unlike early loading, late loading of microcode updates on Arch Linux are enabled by default using {{ic|/usr/lib/tmpfiles.d/linux-firmware.conf}}. After boot the file gets parsed by {{man|8|systemd-tmpfiles-setup.service}} and CPU microcode gets updated.
==== Late loading microcode updates ====


To manually reload the microcode, e.g. after updating the microcode files in {{ic|/usr/lib/firmware/amd-ucode/}} or {{ic|/usr/lib/firmware/intel-ucode/}}, run:
To manually reload the microcode, e.g. after updating the microcode files in {{ic|/usr/lib/firmware/amd-ucode/}} or {{ic|/usr/lib/firmware/intel-ucode/}}, run:
Line 149: Line 185:


This allows to apply newer microcode updates without rebooting the system.
This allows to apply newer microcode updates without rebooting the system.
=== Disabling late microcode updates ===
For AMD systems the CPU microcode will get updated even if {{Pkg|amd-ucode}} is not installed since the files in {{ic|/usr/lib/firmware/amd-ucode/}} are provided by the {{Pkg|linux-firmware}} package ({{Bug|59840}}).
For [[virtual machine]]s and [[Wikipedia:Container (virtualization)|containers]] ({{Bug|46591}}) it is not possible to update the CPU microcode, so you may want to disable microcode updates.
To disable the dangerous late microcode updates, override the [[tmpfile]] {{ic|/usr/lib/tmpfiles.d/linux-firmware.conf}} that is provided by {{Pkg|linux-firmware}}. It can be done by creating a file with the same filename in {{ic|/etc/tmpfiles.d/}}:
# ln -s /dev/null /etc/tmpfiles.d/linux-firmware.conf
== Microcode built in the initramfs ==
If the initramfs generator you use already [https://docs.kernel.org/x86/microcode.html#early-load-microcode prepends the microcode cpio into the initramfs], then [[#Early loading]] and [[#Late loading]] are not necessary. [[dracut]], for example, already does this by default; see {{man|5|dracut.conf|DESCRIPTION}}.
{{Expansion|What about mkinitcpio and Booster?}}
{{Accuracy|What about [[#Enabling early microcode loading in custom kernels]]?}}
{{Expansion|The [[#top|introduction]] does not cover this section.}}


== Verifying that microcode got updated on boot ==
== Verifying that microcode got updated on boot ==
Line 172: Line 190:
Check the kernel messages with ''journalctl'' to see if the microcode has been updated:
Check the kernel messages with ''journalctl'' to see if the microcode has been updated:


  # journalctl -k --grep=microcode
  # 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 {{Pkg|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
One should see something similar to the following on every boot, indicating that microcode is updated very early on:
microcode: Microcode Update Driver: v2.2.


On AMD systems using early loading the output would look something like this:
kernel: microcode: Current revision: 0x00000012
kernel: microcode: Updated early from: 0x0000000e


microcode: microcode updated early to new patch_level=0x0700010f
It is entirely possible, particularly with newer hardware, that there is no microcode update for the CPU.
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:
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.
 
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 ==
== Which CPUs accept microcode updates ==
Line 213: Line 205:
Users may consult either Intel own website or Gentoo's wiki on AMD at the following links to see if a particular model is supported:
Users may consult either Intel own website or Gentoo's wiki on AMD at the following links to see if a particular model is supported:


* [[Gentoo:AMD microcode#Specific firmware only]].
* [[Gentoo:AMD microcode#Microcode firmware files]].
* [https://downloadcenter.intel.com/SearchResult.aspx?lang=eng&keyword=processor%20microcode%20data%20file Intel's download center].
* [https://downloadcenter.intel.com/SearchResult.aspx?lang=eng&keyword=processor%20microcode%20data%20file Intel's download center]{{Dead link|2023|07|30|status=404}}.


=== Detecting available microcode update ===
=== Detecting available microcode update ===


It is possible to find out if the {{ic|intel-ucode.img}} contains a microcode image for the running CPU with {{Pkg|iucode-tool}}.
For Intel, it is possible to find out if the {{ic|/usr/lib/firmware/intel-ucode/}} contains microcode for the running CPU with {{man|8|iucode_tool}}.


# [[Install]] {{Pkg|intel-ucode}} (changing initrd is not required for detection)
# [[Install]] {{Pkg|intel-ucode}} and {{Pkg|iucode-tool}}
# [[Install]] {{Pkg|iucode-tool}}
# Load the {{ic|cpuid}} kernel module: {{bc|# modprobe cpuid}}
# Load the {{ic|cpuid}} kernel module: {{bc|# modprobe cpuid}}
# Extract microcode image and search it for your cpuid:<br/>{{bc|# bsdtar -Oxf /boot/intel-ucode.img {{!}} iucode_tool -tb -lS -}}
# Search it for your cpuid: {{bc|$ iucode_tool -lS /usr/lib/firmware/intel-ucode/}}
# If an update is available, it should show up below ''selected microcodes''
# If an update is available, it should show up below ''selected microcodes''
# The microcode might already be in your vendor bios and not show up loading in ''dmesg''. Compare to the current microcode running {{ic|grep microcode /proc/cpuinfo}}
# The microcode might already be in your vendor bios and not show up loading in ''dmesg''. Compare to the current microcode running {{ic|grep microcode /proc/cpuinfo}}
For AMD, it can be done manually.
# Get {{man|1|lscpu}} or {{ic|/proc/cpuinfo}} output.
# Look at your CPU's family, model and stepping. Convert the values into hexadecimal.
# Match the values accordingly with the list from {{ic|/usr/lib/firmware/amd-ucode/README}}.
# If matched, compare the current running microcode version with the listed {{ic|Patch}} value.
== 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 {{ic|dis_ucode_ldr}} [[kernel parameter]].


== See also ==
== See also ==
Line 231: Line 233:
* [https://flossexperiences.wordpress.com/2013/11/17/updating-microcodes/ Updating microcodes – Experiences in the community]
* [https://flossexperiences.wordpress.com/2013/11/17/updating-microcodes/ Updating microcodes – Experiences in the community]
* [http://inertiawar.com/microcode/ Notes on Intel Microcode updates – Ben Hawkes]
* [http://inertiawar.com/microcode/ Notes on Intel Microcode updates – Ben Hawkes]
* [https://docs.kernel.org/x86/microcode.html Kernel microcode loader – kernel documentation]
* [https://docs.kernel.org/arch/x86/microcode.html Kernel microcode loader – kernel documentation]
* [https://www.anandtech.com/show/8376/intel-disables-tsx-instructions-erratum-found-in-haswell-haswelleep-broadwelly Erratum found in Haswell/Broadwell – AnandTech]
* [https://www.anandtech.com/show/8376/intel-disables-tsx-instructions-erratum-found-in-haswell-haswelleep-broadwelly Erratum found in Haswell/Broadwell – AnandTech]
* [https://gitlab.com/iucode-tool/iucode-tool iucode-tool GitLab project]
* [https://gitlab.com/iucode-tool/iucode-tool iucode-tool GitLab project]
* [https://github.com/platomav/CPUMicrocodes Intel, AMD, VIA & Freescale CPU Microcode Repositories]
* [http://users.atw.hu/instlatx64/ CPUID dumps]

Latest revision as of 16:26, 14 April 2024

This article or section needs expansion.

Reason: (Discuss in Talk:Microcode)

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.

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

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

Early loading

If not compiled into the kernel, microcode must be loaded by the early loader.

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.

mkinitcpio and dracut support generating such combined initramfs files and do so by default. Booster does not support generating combined initramfs.

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
early_cpio
kernel/
kernel/x86/
kernel/x86/microcode/
kernel/x86/microcode/AuthenticAMD.bin
dracut

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

Microcode in a separate initramfs file

Early microcode updates must otherwise be enabled by adding /boot/amd-ucode.img or /boot/intel-ucode.img as the first initrd in the bootloader configuration 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.

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.cfg file. Here is an example:

limine.cfg
DEFAULT_ENTRY=1
TIMEOUT=3

:Arch
    COMMENT=Arch Linux

    PROTOCOL=linux
    KERNEL_PATH=boot:///vmlinuz-linux
    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 own website or Gentoo's wiki on AMD at the following links to see if a particular model is supported:

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. Get lscpu(1) or /proc/cpuinfo output.
  2. Look at your CPU's family, model and stepping. Convert the values into hexadecimal.
  3. Match the values accordingly with the list from /usr/lib/firmware/amd-ucode/README.
  4. If matched, compare the current running microcode version with the listed Patch value.

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