Gentoo Linux installations without initramfs: Updating Intel CPU microcode revisited

In a previous post I described how I updated the CPU microcode on my Clevo W230SS laptop running Gentoo Linux (Stable Branch). Today I decided to check if a newer version of microcode had been released since then and apply it.

First I checked the current state of my installation…

The CPU microcode version in use was the version I had installed last year:

root # grep microcode /proc/cpuinfo
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c

The existing kernel image was still configured as necessary:

root # grep CONFIG_BLK_DEV_INITRD /usr/src/linux/.config
CONFIG_BLK_DEV_INITRD=y
root # grep CONFIG_MICROCODE /usr/src/linux/.config
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
root # CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_MICROCODE_INTEL_EARLY=y
root # CONFIG_MICROCODE_AMD_EARLY is not set
CONFIG_MICROCODE_EARLY=y
root # grep CONFIG_INITRAMFS_SOURCE /usr/src/linux/.config
CONFIG_INITRAMFS_SOURCE=""

The relevant packages I installed last year were sys-apps/microcode-ctl-1.28-r1, sys-apps/microcode-data-20150121-r1 and sys-apps/iucode_tool-1.3. Since then I have updated the installation regularly, and I now found microcode-ctl-1.28-r1 and iucode_tool-1.5 installed but the package microcode-data had been replaced by the new package sys-firmware/intel-microcode-20160607:

root # eix microcode
[I] sys-apps/microcode-ctl
     Available versions:  1.23 (~)1.27 (~)1.28 (~)1.28-r1 {selinux}
     Installed versions:  1.28-r1(15:06:33 26/08/15)(-selinux)
     Homepage:            https://fedorahosted.org/microcode_ctl/
     Description:         Intel processor microcode update utility

[I] sys-firmware/intel-microcode
     Available versions:  20140430 (~)20140624 (~)20140913 20150121 (~)20150121-r1 (~)20151106 (~)20160607 {initramfs monolithic +split-ucode}
     Installed versions:  20160607(23:02:24 25/06/16)(initramfs split-ucode -monolithic)
     Homepage:            http://inertiawar.com/microcode/ https://downloadcenter.intel.com/Detail_Desc.aspx?DwnldID=26083
     Description:         Intel IA32/IA64 microcode update data

Found 2 matches
root # eix iucode_tool
[I] sys-apps/iucode_tool
     Available versions:  (~)1.3 (~)1.5
     Installed versions:  1.5(15:57:21 13/12/15)
     Homepage:            https://gitlab.com/iucode-tool/
     Description:         tool to manipulate Intel X86 and X86-64 processor microcode update collections

I checked the relevant contents of package.use and package.accept_keywords and found that Portage had updated automatically the files to reflect the replacement of package sys-apps/microcode-data by the package sys-firmware/intel-microcode (Portage is an excellent package manager!):

root # cat /etc/portage/package.use/microcode-data
# move sys-apps/microcode-data sys-firmware/intel-microcode
sys-firmware/intel-microcode initramfs
root # cat /etc/portage/package.accept_keywords/microcode-data
# move sys-apps/microcode-data sys-firmware/intel-microcode
sys-firmware/intel-microcode ~amd64
sys-apps/iucode_tool ~amd64

The file /lib/firmware/microcode.cpio and the contents of /lib/firmware/intel-ucode/ had indeed changed since I applied the last CPU microcode update:

root # ls -la /lib/firmware/microcode.cpio
-rw-r--r-- 1 root root 946176 Jun 25 23:02 /lib/firmware/microcode.cpio
root # ls -la /lib/firmware/intel-ucode/
total 1052
drwxr-xr-x  2 root root  4096 Jun 25 23:02 .
drwxr-xr-x 75 root root 16384 Jun 25 23:02 ..
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-03-02
-rw-r--r--  1 root root  6144 Jun 25 23:02 06-05-00
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-05-01
-rw-r--r--  1 root root  6144 Jun 25 23:02 06-05-02
-rw-r--r--  1 root root  8192 Jun 25 23:02 06-05-03
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-06-00
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-06-05
-rw-r--r--  1 root root  6144 Jun 25 23:02 06-06-0a
-rw-r--r--  1 root root  6144 Jun 25 23:02 06-06-0d
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-07-01
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-07-02
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-07-03
-rw-r--r--  1 root root 10240 Jun 25 23:02 06-08-01
-rw-r--r--  1 root root  4096 Jun 25 23:02 06-08-03
-rw-r--r--  1 root root 10240 Jun 25 23:02 06-08-06
-rw-r--r--  1 root root  6144 Jun 25 23:02 06-08-0a
-rw-r--r--  1 root root  6144 Jun 25 23:02 06-09-05
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-0a-00
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-0a-01
-rw-r--r--  1 root root  4096 Jun 25 23:02 06-0b-01
-rw-r--r--  1 root root  4096 Jun 25 23:02 06-0b-04
-rw-r--r--  1 root root  2048 Jun 25 23:02 06-0d-06
-rw-r--r--  1 root root  4096 Jun 25 23:02 06-0e-08
-rw-r--r--  1 root root  8192 Jun 25 23:02 06-0e-0c
-rw-r--r--  1 root root  8192 Jun 25 23:02 06-0f-02
-rw-r--r--  1 root root 12288 Jun 25 23:02 06-0f-06
-rw-r--r--  1 root root  8192 Jun 25 23:02 06-0f-07
-rw-r--r--  1 root root  4096 Jun 25 23:02 06-0f-0a
-rw-r--r--  1 root root 28672 Jun 25 23:02 06-0f-0b
-rw-r--r--  1 root root 12288 Jun 25 23:02 06-0f-0d
-rw-r--r--  1 root root 12288 Jun 25 23:02 06-16-01
-rw-r--r--  1 root root 20480 Jun 25 23:02 06-17-06
-rw-r--r--  1 root root  4096 Jun 25 23:02 06-17-07
-rw-r--r--  1 root root 24576 Jun 25 23:02 06-17-0a
-rw-r--r--  1 root root 14336 Jun 25 23:02 06-1a-04
-rw-r--r--  1 root root 10240 Jun 25 23:02 06-1a-05
-rw-r--r--  1 root root 15360 Jun 25 23:02 06-1c-02
-rw-r--r--  1 root root 20480 Jun 25 23:02 06-1c-0a
-rw-r--r--  1 root root  4096 Jun 25 23:02 06-1d-01
-rw-r--r--  1 root root  6144 Jun 25 23:02 06-1e-04
-rw-r--r--  1 root root  7168 Jun 25 23:02 06-1e-05
-rw-r--r--  1 root root  8192 Jun 25 23:02 06-25-02
-rw-r--r--  1 root root  3072 Jun 25 23:02 06-25-05
-rw-r--r--  1 root root 10240 Jun 25 23:02 06-26-01
-rw-r--r--  1 root root 10240 Jun 25 23:02 06-2a-07
-rw-r--r--  1 root root 16384 Jun 25 23:02 06-2d-06
-rw-r--r--  1 root root 17408 Jun 25 23:02 06-2d-07
-rw-r--r--  1 root root 13312 Jun 25 23:02 06-2f-02
-rw-r--r--  1 root root 12288 Jun 25 23:02 06-3a-09
-rw-r--r--  1 root root 22528 Jun 25 23:02 06-3c-03
-rw-r--r--  1 root root 17408 Jun 25 23:02 06-3d-04
-rw-r--r--  1 root root 13312 Jun 25 23:02 06-3e-04
-rw-r--r--  1 root root 11264 Jun 25 23:02 06-3e-06
-rw-r--r--  1 root root 15360 Jun 25 23:02 06-3e-07
-rw-r--r--  1 root root 32768 Jun 25 23:02 06-3f-02
-rw-r--r--  1 root root 15360 Jun 25 23:02 06-3f-04
-rw-r--r--  1 root root 20480 Jun 25 23:02 06-45-01
-rw-r--r--  1 root root 24576 Jun 25 23:02 06-46-01
-rw-r--r--  1 root root 11264 Jun 25 23:02 06-47-01
-rw-r--r--  1 root root 96256 Jun 25 23:02 06-4e-03
-rw-r--r--  1 root root 25600 Jun 25 23:02 06-4f-01
-rw-r--r--  1 root root 28672 Jun 25 23:02 06-56-02
-rw-r--r--  1 root root 96256 Jun 25 23:02 06-5e-03
-rw-r--r--  1 root root  4096 Jun 25 23:02 0f-00-07
-rw-r--r--  1 root root  6144 Jun 25 23:02 0f-00-0a
-rw-r--r--  1 root root  2048 Jun 25 23:02 0f-01-02
-rw-r--r--  1 root root  6144 Jun 25 23:02 0f-02-04
-rw-r--r--  1 root root  8192 Jun 25 23:02 0f-02-05
-rw-r--r--  1 root root  2048 Jun 25 23:02 0f-02-06
-rw-r--r--  1 root root  6144 Jun 25 23:02 0f-02-07
-rw-r--r--  1 root root  6144 Jun 25 23:02 0f-02-09
-rw-r--r--  1 root root  2048 Jun 25 23:02 0f-03-02
-rw-r--r--  1 root root  2048 Jun 25 23:02 0f-03-03
-rw-r--r--  1 root root  7168 Jun 25 23:02 0f-03-04
-rw-r--r--  1 root root 10240 Jun 25 23:02 0f-04-01
-rw-r--r--  1 root root  2048 Jun 25 23:02 0f-04-03
-rw-r--r--  1 root root  3072 Jun 25 23:02 0f-04-04
-rw-r--r--  1 root root  3072 Jun 25 23:02 0f-04-07
-rw-r--r--  1 root root  9216 Jun 25 23:02 0f-04-08
-rw-r--r--  1 root root  2048 Jun 25 23:02 0f-04-09
-rw-r--r--  1 root root  4096 Jun 25 23:02 0f-04-0a
-rw-r--r--  1 root root  3072 Jun 25 23:02 0f-06-02
-rw-r--r--  1 root root  6144 Jun 25 23:02 0f-06-04
-rw-r--r--  1 root root  2048 Jun 25 23:02 0f-06-05
-rw-r--r--  1 root root  2048 Jun 25 23:02 0f-06-08

So I was in a position to apply the latest CPU microcode…

I mounted the /boot partition:

root # mount /dev/sda1 /boot
root # ls -1 /boot
System.map-3.18.11-gentoo
config-3.18.11-gentoo
grub
lost+found
microcode.cpio
vmlinuz-3.18.11-gentoo

Then I copied the new version of the file microcode.cpio to the /boot partition:

root # cp /lib/firmware/microcode.cpio /boot/

I made sure /boot/grub/grub.cfg still contained the extra line ‘initrd /microcode.cpio‘ I had added in the past:

root # grep -B 15 -A 1 initrd /boot/grub/grub.cfg

### BEGIN /etc/grub.d/10_linux ###
menuentry 'Gentoo GNU/Linux' --class gentoo --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-525a90f1-8ad2-44a3-ade3-20f18a0a9595' {
        load_video
        insmod gzio
        insmod part_msdos
        insmod ext2
        set root='hd0,msdos1'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  f6ffc085-66fe-4bbe-b080-cec355749f85
        else
          search --no-floppy --fs-uuid --set=root f6ffc085-66fe-4bbe-b080-cec355749f85
        fi
        echo    'Loading Linux 3.18.11-gentoo ...'
        linux   /vmlinuz-3.18.11-gentoo root=/dev/sda5 ro  drm_kms_helper.edid_firmware=edid/1920x1080_Clevo_W230SS.bin i915.modeset=1 rcutree.rcu_idle_gp_delay=1 acpi_enforce_resources=lax
        initrd /microcode.cpio
}
submenu 'Advanced options for Gentoo GNU/Linux' $menuentry_id_option 'gnulinux-advanced-525a90f1-8ad2-44a3-ade3-20f18a0a9595' {
        menuentry 'Gentoo GNU/Linux, with Linux 3.18.11-gentoo' --class gentoo --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-3.18.11-gentoo-advanced-525a90f1-8ad2-44a3-ade3-20f18a0a9595' {
                load_video
                insmod gzio
                insmod part_msdos
                insmod ext2
                set root='hd0,msdos1'
                if [ x$feature_platform_search_hint = xy ]; then
                  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  f6ffc085-66fe-4bbe-b080-cec355749f85
                else
                  search --no-floppy --fs-uuid --set=root f6ffc085-66fe-4bbe-b080-cec355749f85
                fi
                echo    'Loading Linux 3.18.11-gentoo ...'
                linux   /vmlinuz-3.18.11-gentoo root=/dev/sda5 ro  drm_kms_helper.edid_firmware=edid/1920x1080_Clevo_W230SS.bin i915.modeset=1 rcutree.rcu_idle_gp_delay=1 acpi_enforce_resources=lax
                initrd /microcode.cpio
        }

Then I rebooted and checked to make sure the new version of CPU microcode is being applied:

root # grep microcode /proc/cpuinfo
microcode       : 0x20
microcode       : 0x20
microcode       : 0x20
microcode       : 0x20
microcode       : 0x20
microcode       : 0x20
microcode       : 0x20
microcode       : 0x20
root # dmesg | grep microcode
[    0.000000] CPU0 microcode updated early to revision 0x20, date = 2016-03-16
[    0.049437] CPU1 microcode updated early to revision 0x20, date = 2016-03-16
[    0.064540] CPU2 microcode updated early to revision 0x20, date = 2016-03-16
[    0.079569] CPU3 microcode updated early to revision 0x20, date = 2016-03-16
[    0.265322] microcode: CPU0 sig=0x306c3, pf=0x10, revision=0x20
[    0.265425] microcode: CPU1 sig=0x306c3, pf=0x10, revision=0x20
[    0.265524] microcode: CPU2 sig=0x306c3, pf=0x10, revision=0x20
[    0.265620] microcode: CPU3 sig=0x306c3, pf=0x10, revision=0x20
[    0.265717] microcode: CPU4 sig=0x306c3, pf=0x10, revision=0x20
[    0.265815] microcode: CPU5 sig=0x306c3, pf=0x10, revision=0x20
[    0.265913] microcode: CPU6 sig=0x306c3, pf=0x10, revision=0x20
[    0.266011] microcode: CPU7 sig=0x306c3, pf=0x10, revision=0x20
[    0.266127] microcode: Microcode Update Driver: v2.00 <tigran@aivazian.fsnet.co.uk>, Peter Oruba

Notice the microcode version has changed from 0x1c to 0x20. Mission accomplished. 🙂

Gentoo Linux installations without initramfs: Updating Intel CPU microcode

This post explains how I configured the Gentoo Linux (amd64) installation on my Clevo W230SS laptop to make it update the Intel CPU microcode using the kernel Microcode Early Update driver.

Back in April I installed Gentoo Linux Stable and built the kernel using the default manual configuration steps given in the Gentoo Handbook, and my installation therefore did not use an initramfs. The contents of the /boot directory were as listed below:

# ls -1 /boot
System.map-3.18.11-gentoo
config-3.18.11-gentoo
grub
lost+found
vmlinuz-3.18.11-gentoo

Contrast the above with the boot directory of the Gentoo Linux Testing (~amd64) installation on my Compal NBLB2 laptop, which does use an initramfs because I built the kernel using the optional genkernel utility:

# ls -1 /boot
System.map-genkernel-x86_64-3.18.11-gentoo
boot
grub
initramfs-genkernel-x86_64-3.18.11-gentoo
kernel-genkernel-x86_64-3.18.11-gentoo
lost+found

Since I wrote my earlier post on updating CPU microcode, the use of a kernel module and initscript to update CPU microcode has been dropped (in Gentoo Linux, at least). This is because updating CPU microcode relatively late in the boot process may cause problems if some processes have started before the update has taken place. The only safe way to update CPU microcode is to use the kernel’s built-in Microcode Early Update driver (METHOD 2 in my earlier post).

Now, new versions of the relevant Gentoo Linux ebuilds (microcode-ctl-1.28-r1, microcode-data-20150121-r1 and iucode_tool-1.3) have recently been released (see Gentoo Bug Report No. 528712). If a Gentoo Linux installation does not use an initramfs, the microcode-data ebuild now includes an ‘initramfs‘ USE flag which you can set in order to create a minimal initramfs to load the CPU microcode at boot. Below I explain in detail how I configured my installation to update the CPU microcode early during boot.

Before doing anything at all, I checked the microcode version for my CPU (Intel Core i7-4810MQ @ 2.80GHz):

# grep microcode /proc/cpuinfo
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
microcode   : 0x12
# dmesg | grep microcode
[    0.262544] microcode: CPU0 sig=0x306c3, pf=0x10, revision=0x12
[    0.262641] microcode: CPU1 sig=0x306c3, pf=0x10, revision=0x12
[    0.262740] microcode: CPU2 sig=0x306c3, pf=0x10, revision=0x12
[    0.262841] microcode: CPU3 sig=0x306c3, pf=0x10, revision=0x12
[    0.262939] microcode: CPU4 sig=0x306c3, pf=0x10, revision=0x12
[    0.263038] microcode: CPU5 sig=0x306c3, pf=0x10, revision=0x12
[    0.263138] microcode: CPU6 sig=0x306c3, pf=0x10, revision=0x12
[    0.263236] microcode: CPU7 sig=0x306c3, pf=0x10, revision=0x12
[    0.263367] microcode: Microcode Update Driver: v2.00 , Peter Oruba

Fortunately I did not need to rebuild the kernel as I had already configured it back in April when I installed Gentoo, with a view to implementing early microcode updating at some point:

# grep CONFIG_BLK_DEV_INITRD /usr/src/linux/.config
CONFIG_BLK_DEV_INITRD=y
# grep CONFIG_MICROCODE /usr/src/linux/.config
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
# CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_MICROCODE_INTEL_EARLY=y
# CONFIG_MICROCODE_AMD_EARLY is not set
CONFIG_MICROCODE_EARLY=y
# grep CONFIG_INITRAMFS_SOURCE /usr/src/linux/.config
CONFIG_INITRAMFS_SOURCE=""

Then I set the initramfs USE flag and unmasked the ~amd64 ebuilds created by Gentoo developer SpanKY (microcode-ctl-1.28-r1.ebuild, microcode-data-20150121-r1.ebuild and iucode_tool-1.3.ebuild) as discussed in the above-mentioned Gentoo bug report:

# cat /etc/portage/package.use/microcode-data
sys-apps/microcode-data initramfs
# cat /etc/portage/package.accept_keywords/microcode-data
sys-apps/microcode-data ~amd64
sys-apps/iucode_tool ~amd64
# cat /etc/portage/package.accept_keywords/microcode-ctl
sys-apps/microcode-ctl ~amd64

Then I merged the packages:

# emerge --ask microcode-ctl microcode-data

This resulted in the following files:

# ls -la /lib/firmware/microcode.cpio
-rw-r--r-- 1 root root 663552 Aug 26 15:06 /lib/firmware/microcode.cpio
# ls -la /lib/firmware/intel-ucode
total 768
drwxr-xr-x  2 root root  4096 Aug 26 15:06 .
drwxr-xr-x 62 root root 16384 Aug 26 15:06 ..
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-03-02
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-05-00
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-05-01
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-05-02
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-05-03
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-06-00
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-06-05
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-06-0a
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-06-0d
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-07-01
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-07-02
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-07-03
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-08-01
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-08-03
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-08-06
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-08-0a
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-09-05
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-0a-00
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-0a-01
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-0b-01
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-0b-04
-rw-r--r--  1 root root  2048 Aug 26 15:06 06-0d-06
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-0e-08
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-0e-0c
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-0f-02
-rw-r--r--  1 root root 12288 Aug 26 15:06 06-0f-06
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-0f-07
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-0f-0a
-rw-r--r--  1 root root 28672 Aug 26 15:06 06-0f-0b
-rw-r--r--  1 root root 12288 Aug 26 15:06 06-0f-0d
-rw-r--r--  1 root root 12288 Aug 26 15:06 06-16-01
-rw-r--r--  1 root root 20480 Aug 26 15:06 06-17-06
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-17-07
-rw-r--r--  1 root root 24576 Aug 26 15:06 06-17-0a
-rw-r--r--  1 root root 14336 Aug 26 15:06 06-1a-04
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-1a-05
-rw-r--r--  1 root root 15360 Aug 26 15:06 06-1c-02
-rw-r--r--  1 root root 20480 Aug 26 15:06 06-1c-0a
-rw-r--r--  1 root root  4096 Aug 26 15:06 06-1d-01
-rw-r--r--  1 root root  6144 Aug 26 15:06 06-1e-04
-rw-r--r--  1 root root  7168 Aug 26 15:06 06-1e-05
-rw-r--r--  1 root root  8192 Aug 26 15:06 06-25-02
-rw-r--r--  1 root root  3072 Aug 26 15:06 06-25-05
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-26-01
-rw-r--r--  1 root root 10240 Aug 26 15:06 06-2a-07
-rw-r--r--  1 root root 16384 Aug 26 15:06 06-2d-06
-rw-r--r--  1 root root 17408 Aug 26 15:06 06-2d-07
-rw-r--r--  1 root root 13312 Aug 26 15:06 06-2f-02
-rw-r--r--  1 root root 12288 Aug 26 15:06 06-3a-09
-rw-r--r--  1 root root 21504 Aug 26 15:06 06-3c-03
-rw-r--r--  1 root root 14336 Aug 26 15:06 06-3d-04
-rw-r--r--  1 root root 13312 Aug 26 15:06 06-3e-04
-rw-r--r--  1 root root 11264 Aug 26 15:06 06-3e-06
-rw-r--r--  1 root root 15360 Aug 26 15:06 06-3e-07
-rw-r--r--  1 root root 28672 Aug 26 15:06 06-3f-02
-rw-r--r--  1 root root 20480 Aug 26 15:06 06-45-01
-rw-r--r--  1 root root 23552 Aug 26 15:06 06-46-01
-rw-r--r--  1 root root  4096 Aug 26 15:06 0f-00-07
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-00-0a
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-01-02
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-02-04
-rw-r--r--  1 root root  8192 Aug 26 15:06 0f-02-05
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-02-06
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-02-07
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-02-09
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-03-02
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-03-03
-rw-r--r--  1 root root  7168 Aug 26 15:06 0f-03-04
-rw-r--r--  1 root root 10240 Aug 26 15:06 0f-04-01
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-04-03
-rw-r--r--  1 root root  3072 Aug 26 15:06 0f-04-04
-rw-r--r--  1 root root  3072 Aug 26 15:06 0f-04-07
-rw-r--r--  1 root root  9216 Aug 26 15:06 0f-04-08
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-04-09
-rw-r--r--  1 root root  4096 Aug 26 15:06 0f-04-0a
-rw-r--r--  1 root root  3072 Aug 26 15:06 0f-06-02
-rw-r--r--  1 root root  6144 Aug 26 15:06 0f-06-04
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-06-05
-rw-r--r--  1 root root  2048 Aug 26 15:06 0f-06-08

(By the way, the file 06-3c-03 is the microcode file for my particular CPU: Family 06h, Model 03Ch, Stepping 03h, as determined from the CPU World Web site.)

Then I copied to the boot directory the cpio file created when I merged the packages:

# cp /lib/firmware/microcode.cpio /boot/

Then I added an initrd line to /boot/grub/grub.cfg as shown below:

# grep -B 15 -A 1 initrd /boot/grub/grub.cfg

### BEGIN /etc/grub.d/10_linux ###
menuentry 'Gentoo GNU/Linux' --class gentoo --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-525a90f1-8ad2-44a3-ade3-20f18a0a9595' {
        load_video
        insmod gzio
        insmod part_msdos
        insmod ext2
        set root='hd0,msdos1'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  f6ffc085-66fe-4bbe-b080-cec355749f85
        else
          search --no-floppy --fs-uuid --set=root f6ffc085-66fe-4bbe-b080-cec355749f85
        fi
        echo    'Loading Linux 3.18.11-gentoo ...'
        linux   /vmlinuz-3.18.11-gentoo root=/dev/sda5 ro  drm_kms_helper.edid_firmware=edid/1920x1080_Clevo_W230SS.bin i915.modeset=1 rcutree.rcu_idle_gp_delay=1
        initrd /microcode.cpio
}

After rebooting:

# grep microcode /proc/cpuinfo
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
microcode       : 0x1c
# dmesg | grep microcode
[    0.000000] CPU0 microcode updated early to revision 0x1c, date = 2014-07-03
[    0.049968] CPU1 microcode updated early to revision 0x1c, date = 2014-07-03
[    0.065070] CPU2 microcode updated early to revision 0x1c, date = 2014-07-03
[    0.080101] CPU3 microcode updated early to revision 0x1c, date = 2014-07-03
[    0.268736] microcode: CPU0 sig=0x306c3, pf=0x10, revision=0x1c
[    0.268838] microcode: CPU1 sig=0x306c3, pf=0x10, revision=0x1c
[    0.268935] microcode: CPU2 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269034] microcode: CPU3 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269131] microcode: CPU4 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269230] microcode: CPU5 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269329] microcode: CPU6 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269448] microcode: CPU7 sig=0x306c3, pf=0x10, revision=0x1c
[    0.269570] microcode: Microcode Update Driver: v2.00 , Peter Oruba

As you can see above, the microcode early update kernel driver updates the microcode version to 0x1c at boot (cf. 0x12 originally). If you have a different model of CPU to mine, of course the version in your case could be different.

Note that the line ‘initrd /lib/firmware/microcode.cpio‘ in the file grub.cfg does not work for me. It has to be ‘initrd /microcode.cpio‘ and the file microcode.cpio has to be in the /boot directory:

# ls /boot
System.map-3.18.11-gentoo  config-3.18.11-gentoo  grub  lost+found  microcode.cpio  vmlinuz-3.18.11-gentoo

Note also that the precise steps specified in Comment #41 of Gentoo Bug Report No. 528712 do not work for me and others (see Gentoo Forums thread microcode-data-20150121-r1 with USE=initramfs: kernel panic). If I build the kernel with CONFIG_INITRAMFS_SOURCE="/lib/firmware/microcode.cpio", delete the line ‘initrd /microcode‘ from grub.cfg, delete the file /boot/microcode.cpio and reboot, the kernel panics and the last two console lines are as follows:

[    3.142079] drm_kms_helper: panic occurred, switching back to text console
[    3.142879] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,5)

Unless Gentoo developer SpanKY explains how he managed to get the procedure he gave in Comment #41 of Gentoo Bug Report No. 528712 to work, it seems the normal behaviour when applying the steps he gave would be for the kernel to panic. Even Gentoo developer Daniel Pielmeier experienced a kernel panic when he applied SpanKY‘s steps (Comment #54 of Gentoo Bug Report No. 528712).

As the procedure I gave above works fine, I therefore reverted to using CONFIG_INITRAMFS_SOURCE="", copying /lib/firmware/microcode.cpio to /boot/microcode.cpio again and re-adding the line ‘initrd /microcode.cpio‘ in the file grub.cfg. However, if you did not have an initramfs and were able to get the precise procedure given in Comment #41 of Gentoo Bug Report #528712 to work, please post a comment here.

Updating Intel CPU microcode from Gentoo Linux

Updates to CPU microcode have to be re-applied each time the computer is booted, because the memory updated is volatile (despite the term ‘firmware’ also being used for microcode). Below I describe two methods (there are others) of applying CPU microcode updates in Gentoo Linux. My main laptop has an Intel CPU so I focus here on Intel microcode updates. The procedure is almost the same for AMD CPUs, but the AMD CPU binary update file (‘binary blob’) is installed by the sys-kernel/linux-firmware package.

METHOD 1: Use an initscript in the boot runlevel with a kernel module

Until recently I was using an initscript named microcode_ctl, which uses a program (also named microcode_ctl) and a kernel module (microcode.ko) to update the Intel CPU microcode during boot. This was straightforward to set up in Gentoo Linux:

1. Build the kernel with CONFIG_MICROCODE=m and CONFIG_MICROCODE_INTEL=y.

This is what I configured in the kernel:

# grep -i microcode /usr/src/linux/.config
CONFIG_MICROCODE=m
CONFIG_MICROCODE_INTEL=y
# CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
# CONFIG_MICROCODE_INTEL_EARLY is not set
# CONFIG_MICROCODE_AMD_EARLY is not set

2. Install two packages and add an OpenRC initscript to the boot runlevel:

# emerge microcode-data microcode-ctl
# rc-update add microcode_ctl boot

The initscript will re-update the CPU microcode every time the computer is rebooted.

Installing the package microcode-data downloads a compressed file (microcode-yyyymmdd.tgz) from the Intel Download Centre, extracts a text file named microcode.dat and parses the text in it to create a set of binary ‘blobs’ in the directory /lib/firmware/intel-ucode/ (one blob for each model of Intel CPU).

Before rebooting, check the revision of microcode in the CPU (the microcode revision is shown for each logical core):

# This is for the Core i7-720QM CPU in my Compal NBLB2 laptop.
# grep microcode /proc/cpuinfo
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3

If I use this method of updating the microcode, the initscript runs after the message ‘Waiting for uevents to be processed ...‘ is displayed on VT1 while booting. After the module has performed the update, the microcode revision in the CPU’s logical cores has changed:

# grep microcode /proc/cpuinfo
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
# dmesg | grep microcode
[ 15.749533] microcode: CPU0 sig=0x106e5, pf=0x10, revision=0x3
[ 15.834790] microcode: CPU0 sig=0x106e5, pf=0x10, revision=0x3
[ 15.835530] microcode: CPU0 updated to revision 0x7, date = 2013-08-20
[ 15.835544] microcode: CPU1 sig=0x106e5, pf=0x10, revision=0x3
[ 15.835587] microcode: CPU1 sig=0x106e5, pf=0x10, revision=0x3
[ 15.836241] microcode: CPU1 updated to revision 0x7, date = 2013-08-20
[ 15.836257] microcode: CPU2 sig=0x106e5, pf=0x10, revision=0x3
[ 15.836299] microcode: CPU2 sig=0x106e5, pf=0x10, revision=0x3
[ 15.836953] microcode: CPU2 updated to revision 0x7, date = 2013-08-20
[ 15.837063] microcode: CPU3 sig=0x106e5, pf=0x10, revision=0x3
[ 15.837128] microcode: CPU3 sig=0x106e5, pf=0x10, revision=0x3
[ 15.837767] microcode: CPU3 updated to revision 0x7, date = 2013-08-20
[ 15.837857] microcode: CPU4 sig=0x106e5, pf=0x10, revision=0x3
[ 15.837968] microcode: CPU4 sig=0x106e5, pf=0x10, revision=0x3
[ 15.838605] microcode: CPU4 updated to revision 0x7, date = 2013-08-20
[ 15.838634] microcode: CPU5 sig=0x106e5, pf=0x10, revision=0x3
[ 15.838681] microcode: CPU5 sig=0x106e5, pf=0x10, revision=0x3
[ 15.839357] microcode: CPU5 updated to revision 0x7, date = 2013-08-20
[ 15.839390] microcode: CPU6 sig=0x106e5, pf=0x10, revision=0x3
[ 15.839453] microcode: CPU6 sig=0x106e5, pf=0x10, revision=0x3
[ 15.840121] microcode: CPU6 updated to revision 0x7, date = 2013-08-20
[ 15.840180] microcode: CPU7 sig=0x106e5, pf=0x10, revision=0x3
[ 15.840274] microcode: CPU7 sig=0x106e5, pf=0x10, revision=0x3
[ 15.840911] microcode: CPU7 updated to revision 0x7, date = 2013-08-20
[ 15.840997] microcode: Microcode Update Driver: v2.00 , Peter Oruba
[ 26.940662] microcode: Microcode Update Driver: v2.00 removed.

Notice that the microcode update occurred in the period from 15.749533 to 15.840997 seconds after the kernel started running, and the microcode was updated from revision 0x3 to 0x7.

METHOD 2: Use the kernel’s built-in Early Update driver

Although the initscript method works perfectly in my case and the update is complete by the time the laptop has finished booting, I wanted to update the CPU microcode earlier. Updating microcode early can fix CPU issues before they occur during kernel boot time. It is possible to configure the kernel to update microcode early by setting CONFIG_MICROCODE_EARLY and CONFIG_MICROCODE_INTEL_EARLY in the kernel. See /usr/src/linux/Documentation/x86/early-microcode.txt for details. That document only refers to initrd files, but, in fact, it also applies to initramfs files.

The Early Update kernel driver will align misaligned microcode data (see Notes on Intel Microcode Updates and [PATCH 7/8] x86, microcode, intel: guard against misaligned microcode data), but you can pre-align the data yourself if you wish by using a .padding file as explained on the latter page. However I did not bother doing that; I leave the Early Update kernel driver to take care of aligning the microcode, as the time penalty to align it is small compared to the overall update time.

It is possible to download the latest compressed Intel microcode data file yourself from the Intel Download Centre. The latest file released is microcode-20140913.tgz at the time of writing. It contains only a text file named microcode.dat, not the required binary blob. Actually, microcode.dat contains data in text format for several Intel CPU models. The microcode.dat file should reside in the directory /lib/firmware/. In the case of Gentoo it is a waste of time manually obtaining the microcode.dat file this way, as there is no tool in Gentoo specifically for creating a binary blob from the microcode.dat file. Therefore just install the Gentoo package sys-apps/microcode-data (which you would have done in any case if you were using the microcode_ctl initscript to load the microcode update to the CPU) and it will automatically download the compressed file from the Intel Web site, unpack it, copy the file microcode.dat to /lib/firmware/ and create the binary blobs in the directory /lib/firmware/intel-ucode/.

You may have read of a tool named intel-microcode2ucode used in other Linux distributions. Gentoo does not build intel-microcode2ucode (the source code of which is included in the Gentoo package sys-apps/microcode-data) as a stand-alone tool, but the act of installing microcode-data creates the required binary files in /lib/firmware/intel-ucode/. i.e. the following command does the complete job:

# emerge microcode-data

Check that the microcode files for the various CPU models were created when microcode-data was installed:

# ls /lib/firmware/intel-ucode/
06-03-02 06-05-03 06-06-0d 06-08-01 06-09-05 06-0b-04 06-0f-02 06-0f-0b 06-17-07 06-1c-02 06-1e-05 06-2a-07 06-3a-09 06-3e-07 0f-00-07 0f-02-05 0f-03-02 0f-04-03 0f-04-09 0f-06-05
06-05-00 06-06-00 06-07-01 06-08-03 06-0a-00 06-0d-06 06-0f-06 06-0f-0d 06-17-0a 06-1c-0a 06-25-02 06-2d-06 06-3c-03 06-3f-02 0f-00-0a 0f-02-06 0f-03-03 0f-04-04 0f-04-0a 0f-06-08
06-05-01 06-06-05 06-07-02 06-08-06 06-0a-01 06-0e-08 06-0f-07 06-16-01 06-1a-04 06-1d-01 06-25-05 06-2d-07 06-3e-04 06-45-01 0f-01-02 0f-02-07 0f-03-04 0f-04-07 0f-06-02
06-05-02 06-06-0a 06-07-03 06-08-0a 06-0b-01 06-0e-0c 06-0f-0a 06-17-06 06-1a-05 06-1e-04 06-26-01 06-2f-02 06-3e-06 06-46-01 0f-02-04 0f-02-09 0f-04-01 0f-04-08 0f-06-04

I looked in /proc/cpuinfo to confirm the model of CPU in my laptop:

$ grep model /proc/cpuinfo
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz

I was able to find the CPUID and other data for that model from the Web site CPU World:

CPUID 106E5
Family 6 (06 hex)
Model 30 (1E hex)
Stepping 5 (05 hex)

Therefore the file /lib/firmware/intel-ucode/06-1e-05 (FamilyModelStepping in hexadecimal) is the binary blob for my specific CPU model.

First I used genkernel to rebuild the current kernel with CONFIG_MICROCODE_EARLY=y and CONFIG_MICROCODE_INTEL_EARLY=y.

# mount /dev/sda3 /boot # /boot is on a separate partition in my installation.

# Backup the files of the existing kernel image and initramfs:
# cp /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1 /home/fitzcarraldo/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.bak
# cp /boot/kernel-genkernel-x86_64-3.17.1-gentoo-r1 /home/fitzcarraldo/kernel-genkernel-x86_64-3.17.1-gentoo-r1.bak
# cp /boot/System.map-genkernel-x86_64-3.17.1-gentoo-r1 /home/fitzcarraldo/System.map-genkernel-x86_64-3.17.1-gentoo-r1.bak

# Now rebuild the kernel:
# zcat /proc/config.gz > /usr/src/config
# genkernel --kernel-config=/usr/src/config --menuconfig --splash=Emergance --disklabel all # Set CONFIG_MICROCODE_EARLY and CONFIG_MICROCODE_INTEL_EARLY.
# emerge @module-rebuild
# grub2-mkconfig -o /boot/grub/grub.cfg

This is what I have after rebuilding the kernel:

# grep -i microcode /usr/src/linux/.config
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
# CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_MICROCODE_INTEL_EARLY=y
# CONFIG_MICROCODE_AMD_EARLY is not set
CONFIG_MICROCODE_EARLY=y

Then I prepended the cpio file containing the binary blob to the initramfs file (see the instructions in /usr/src/linux/Documentation/x86/early-microcode.txt):

# mkdir -p /boot/initrd/kernel/x86/microcode
# cd /boot/initrd
# cp /lib/firmware/intel-ucode/06-1e-05 kernel/x86/microcode/GenuineIntel.bin
# find . | cpio -o -H newc >../ucode.cpio
# cd ..
# cp /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1 /home/fitzcarraldo/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.bak.early # Backup the recently-built initramfs first.
# cat ucode.cpio /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1 >/boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.ucode
# cp /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.ucode /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1
# rm /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.ucode
# umount /boot
# rc-update del microcode_ctl boot # Disable the initscript so that microcode.ko will no longer be used when I reboot.

Reboot.

Use the following commands to check if the CPU microcode has been updated:

# grep microcode /proc/cpuinfo
# dmesg | grep microcode

There is no point looking in /var/log/messages, because syslog-ng has not started running when the early microcode update occurs.

# grep microcode /proc/cpuinfo
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
# dmesg | grep microcode
[ 0.252234] CPU1 microcode updated early to revision 0x7, date = 2013-08-20
[ 0.265389] CPU2 microcode updated early to revision 0x7, date = 2013-08-20
[ 0.278696] CPU3 microcode updated early to revision 0x7, date = 2013-08-20
[ 1.888471] microcode: CPU0 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888481] microcode: CPU1 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888491] microcode: CPU2 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888498] microcode: CPU3 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888506] microcode: CPU4 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888515] microcode: CPU5 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888523] microcode: CPU6 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888534] microcode: CPU7 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888597] microcode: Microcode Update Driver: v2.00 , Peter Oruba

Compare the update time in the dmesg output above with the update time in the dmesg output for an update done using the initscript (Method 1, further up). With the Early Update driver, the update was complete in 0.278696 seconds. With the initscript and kernel module, the update was complete in 15.840911 seconds. Quite a difference.

I do not know why the dmesg output does not have a message for Core 0 in the group of messages before 1.000000 second elapsed. The message at 1.888471 shows it was updated, so I assume the kernel ring buffer was not large enough and the message was overwritten. Cores 1, 2 and 3 were updated in the period between 0.252234 and 0.278696 seconds, and then all eight logical cores are listed in the period between 1.888471 and 1.888597 seconds. I’m not sure of the precise messages expected, but they look similar to the results obtained by users in other distributions, such as the following CrunchBang Linux output:

$ uname -a
Linux crunchbang 3.10-12.dmz.1-liquorix-amd64 #1 ZEN SMP PREEMPT Sun Sep 15 17:29:51 UTC 2013 x86_64 GNU/Linux
$ dmesg | grep microcode
CPU0 microcode updated early to revision 0x19, date = 2013-06-13
CPU1 microcode updated early to revision 0x19, date = 2013-06-13
CPU2 microcode updated early to revision 0x19, date = 2013-06-13
CPU3 microcode updated early to revision 0x19, date = 2013-06-13
microcode: CPU0 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU1 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU2 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU3 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU4 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU5 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU6 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU7 sig=0x306a9, pf=0x10, revision=0x19
microcode: Microcode Update Driver: v2.00 , Peter Oruba
$ cat /proc/cpuinfo | grep microcode | uniq
microcode : 0x19

Finally, I deleted the temporary work directory and files:

# mount /dev/sda3 /boot
# rm -rf /boot/initrd/
# rm /boot/ucode.cpio
# rm /home/fitzcarraldo/kernel-genkernel-x86_64-3.17.1-gentoo-r1.bak
# rm /home/fitzcarraldo/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.bak
# rm /home/fitzcarraldo/System.map-genkernel-x86_64-3.17.1-gentoo-r1.bak

# Optional. Could keep the following file in case Intel issues a new microcode.dat file and I want to create a new concatenated initramfs file:
# rm /home/fitzcarraldo/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.bak.early

Of course, you will need to repeat the whole process and create a new concatenated initramfs file in any of the following cases:

a) you build a new version of the kernel;

b) you rebuild the current version of the kernel with different configuration settings;

c) Intel releases a new version of the microcode (which does not happen often).

It seems the Early Update driver still has some bugs, so I expect the message output to change in future kernel releases. See e.g. [PATCH 0/8] x86, microcode, intel: fixes and enhancements, [PATCH 3/8] x86, microcode, intel: clarify log messages, Re: [PATCH 3/8] x86, microcode, intel: clarify log messages and a bunch of other very recent posts in the kernel mailing list regarding the Early Update driver and CPU microcode updates.

UPDATE (September 1, 2015): Since I wrote the above post, the use of a kernel module and initscript to update CPU microcode has been dropped (in Gentoo Linux, at least). This is because updating CPU microcode relatively late in the boot process may cause problems if some processes have started before the update has taken place. The only safe way to update CPU microcode is to use the kernel’s built-in Microcode Early Update driver (METHOD 2 above). New versions of the relevant Gentoo Linux ebuilds (microcode-ctl-1.28-r1, microcode-data-20150121-r1 and iucode_tool-1.3) have recently been released (see Gentoo Bug Report No. 528712). If a Gentoo Linux installation does not use an initramfs, the microcode-data ebuild now includes an ‘initramfs‘ USE flag which you can set in order to create a minimal initramfs to load the CPU microcode at boot (see my latest post for details).