From Lyceum
Jump to: navigation, search

CPU Microcode Updates

Linux supports applying CPU microcode updates at runtime.

Should you do so? Have microcode updates already been applied? How do you apply them?

Read on.

Microcode Black Box

Ever see a boot message like:

 perf_event_intel: PEBS disabled due to CPU errata, please upgrade microcode

Intel does not issue release notes with microcode, thus they are a black box. Despite not knowing precisely what fixes they contain, it seems to me applying the manufacturers intended update is likely to do more good than harm.

Granted, a microcode update is not going to magically create new circuitry and upgrade your i7 to support AVX, but I've been interested in how all this worked for a while and so decided to dive in.

Microcode is distributed in ACSII encoded cryptographically signed binary files which are available for Download from Intel. A variety of tools exist to extract and apply updates from this file.

Ref Sites

https://wiki.archlinux.org/index.php/microcode

http://stackoverflow.com/questions/4366837/what-is-intel-microcode

https://sites.google.com/site/easylinuxtipsproject/microcode

http://www.urbanmyth.org/microcode/

=> http://web.archive.org/web/20120226174302/http://urbanmyth.org/microcode/

Before installing microcode package

Suse 13.1 on my MacBook Air showed:

#dmesg | grep micro
[    0.060660] perf_event_intel: PEBS disabled due to CPU errata, please upgrade microcode
[    0.570778] microcode: CPU0 sig=0x206a7, pf=0x10, revision=0x1a
[    0.570786] microcode: CPU1 sig=0x206a7, pf=0x10, revision=0x1a
[    0.570795] microcode: CPU2 sig=0x206a7, pf=0x10, revision=0x1a
[    0.570804] microcode: CPU3 sig=0x206a7, pf=0x10, revision=0x1a
[    0.570842] microcode: Microcode Update Driver: v2.00 <[email protected]>, Peter Oruba

This shows no patch has been applied.

Install microcode via Linux Package Manager

You can likely update the microcode by installing one package using your distribution's package manager. Here is a Suse 13.1 example.

zypper info ucode-intel

AMD microcode is part of kernel-firmware package. Earlier distro versions may use microcode_ctl, see below.

For ubuntu: apt-get install intel-microcode

Installs microcodes to /lib/firmware/intel-ucode and generates an new initrd containing intel_microcode.

After installing, dmesg shows update has been applied:

# dmesg | tail
[ 1729.436898] microcode: CPU0 sig=0x206a7, pf=0x10, revision=0x1a
[ 1729.437442] microcode: CPU0 updated to revision 0x29, date = 2013-06-12
[ 1729.437487] microcode: CPU1 sig=0x206a7, pf=0x10, revision=0x1a
[ 1729.437795] microcode: CPU1 updated to revision 0x29, date = 2013-06-12
[ 1729.437830] microcode: CPU2 sig=0x206a7, pf=0x10, revision=0x1a
[ 1729.438278] microcode: CPU2 updated to revision 0x29, date = 2013-06-12
[ 1729.438348] microcode: CPU3 sig=0x206a7, pf=0x10, revision=0x1a
[ 1729.438798] microcode: CPU3 updated to revision 0x29, date = 2013-06-12

Humm version 0x29 compared to 0x1a = 15 version difference from the unpatched version.

That's all you have to do in current distros.

The remaining sections describe downloading latest firmware from Intel and using related tools.

CPU Family to microcode Hex Identifiers

Other interesting scripts installed:

 /lib/mkinitrd/scripts/setup-intel_microcode.sh
 /lib/mkinitrd/scripts/boot-intel_microcode.sh

Both are available at:

http://lists.opensuse.org/archive/opensuse-commit/2013-12/msg00548.html

Running lscpu will show family, model and stepping in decimal. These are converted to hex-hex-hex to match the extracted microcodes

Note: As of Linux 3.4.2, the microcode update module is loaded automatically if your processor support it, no user interaction is required. (If microcode is is /etc/firmware or /lib/firmware you should be good to go.)

Manually download and apply

Best to just use package version and let it build the initrd, etc.

If you are die hard, or the packaged version is outdated then search Intel Downloads site for CPU Type, firmware downloads for something like:

Linux* Processor Microcode Data File 1/22/2014 20140122 Latest Firmware

Example: https://downloadcenter.intel.com/Detail_Desc.aspx?agr=Y&ProdId=3426&DwnldID=23574

"The microcode data file contains the latest microcode definitions for all Intel processors. Intel releases microcode updates to correct processor behavior as documented in the respective processor specification updates. While the regular approach to getting this microcode update is via a BIOS upgrade, Intel realizes that this can be an administrative hassle. The Linux Operating System and VMware ESX products have a mechanism to update the microcode after booting. For example, this file will be used by the operating system mechanism if the file is placed in the /etc/firmware directory of the Linux system.

Apply with: modprobe microcode"

In newer kernels this kernel module should apply a matching firmware from /lib/firmware if available.

First you have to extract the microcodes though.

Extracting microcodes

# generate_microcode //contained in microcode_ctl, ucode-intel, etc.
open /lib/firmware/microcode.dat: No such file or directory

Extract and specify the .dat downloaded from the intel site:

tar tzvf microcode-20140122.tgz 
-rw-r--r-- root/root   1805178 2014-01-22 10:06 microcode.dat

The .dat file is actually ASCII containing sections for each CPU. There are cryptographic checks that occur behind the scenes on all this.

Extracts to intel-ucode which can then be copied to /lib/firmware/ overwriting versions provided by package above

(See notes above on converting CPU family, model, stepping to hex to match the micocode you need.)

Loading microcode

Using microcode_ctl package (E.g Suse 12.3)

Suse 12.3 uses the microcode_ctl package rather than the newer ucode-intel Installs microcodes to /lib/firmware/intel-ucode/, but on Suse 12.3 these were outdated so I extracted the appropriate update and manually applied it.

(Note this is a different system and microcode version than above)

 [   19.144923] microcode: CPU0 sig=0x106e5, pf=0x2, revision=0x3
 [   21.278236] microcode: CPU0 updated to revision 0x5, date = 2011-09-01

Ger your CPU info:

 lscpu
 CPU family:            6
 Model:                 30
 Stepping:              5

Convert to hex: 06-1e-05

Download and apply latest microcode from Intel link above

microcode_ctl -u -f microcode.dat 
microcode_ctl: writing microcode (length: 600064)
microcode_ctl: microcode successfuly written to /dev/cpu/microcode

Dmesg now shows:

 [52940.474212] microcode: CPU0 updated to revision 0x7, date = 2013-08-20
 [52940.474677] microcode: CPU1 updated to revision 0x7, date = 2013-08-20

To make it happen on reboot, you could put microcode_ctl -u -f microcode.dat in a boot script.

Or use generate_microcode (provided by microcode_ctl) to extract individual microcodes: generate_microcode microcode.data

Verify if the md5sum of the extracted version is different than the currently installed:

md5sum intel-ucode/06-1e-05 /lib/firmware/intel-ucode/06-1e-05 5a903a9482c8ccc9b04997861d36829a intel-ucode/06-1e-05 5bc68dc6d150452ae91b9a2ab672babb /lib/firmware/intel-ucode/06-1e-05

If so copy individual microcodes to /var/lib/firmware/intel-ucode where they should be found and loaded by a 3.4> kernel automatically on boot.

Another method:

Copy microcode to /lib/firware/intel-ucode and then

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


Kernel Support

grep -i microcode /boot/config-`uname -r`
CONFIG_MICROCODE=m
CONFIG_MICROCODE_INTEL=y
CONFIG_MICROCODE_AMD=y
CONFIG_MICROCODE_OLD_INTERFACE=y

modinfo microcode