Intel Microcode unter FreeBSD aktualisieren

Aus Thomas-Krenn-Wiki
Zur Navigation springen Zur Suche springen

FreeBSD bietet Unterstützung den Microcode eines Prozessors beim Starten oder zur Laufzeit zu aktualisieren. In diesem Artikel zeigen wir anhand eines Servers mit FreeBSD 12.0 wie Sie die Intel Microcode Version überprüfen und bei Bedarf neuere Microcode Versionen einspielen.

Beispielsetup

In diesem Beispiel verwenden wir folgendes Setup:

Das Beispiel wurde am 16.01.2019 mit dem zu diesem Zeitpunkt aktuellsten verfügbaren BIOS-, Microcode- und Software-Versionen durchgeführt. Es zeigt damit anschaulich, wie in sicherheitskritischen Umgebungen die neuesten Sicherheitsupdates sowohl in Bezug auf den Microcode, als auch in Bezug auf Software-Updates eingespielt werden können.

Aktuelle Microcode Version auslesen

Intel führt im Microcode Update Guidance vom 08.08.2018 (siehe Intel Microcode - Microcode Versionen) die neue Microcode Version 0x25 für den hier im Beispiel verwendeten Intel Celeron G1820T (CPUID 306c3) an.

Informationen zur CPU (Name, CPUID, Microcode-Version) können mit dem Tool x86info nach dem Laden des Moduls cpuctl abgefragt werden:

kldload cpuctl
x86info -a

In der Ausgabe ist in der Zeile Microcode version die Version ersichtlich (im Beispiel 0x0000000000000024), die CPUID findet in der zweiten Zeile in der eax Ausgabe (im Beispiel 000306c3):

root@freebsd12:~ # kldload cpuctl
root@freebsd12:~ # x86info -a
x86info v1.31pre
MP Table:
#	APIC ID	Version	State		Family	Model	Step	Flags
#	 0	 0x15	 BSP, usable	 6	 12	 3	 0x0381
#	 2	 0x15	 AP, usable	 6	 12	 3	 0x0381

Found 2 identical CPUs
Extended Family: 0 Extended Model: 3 Family: 6 Model: 60 Stepping: 3
Type: 0 (Original OEM)
CPU Model (x86info's best guess): Xeon E3 [Haswell]
Processor name string (BIOS programmed): Intel(R) Celeron(R) CPU G1820T @ 2.40GHz

[...]

Microcode version: 0x0000000000000024

eax in: 0x00000000, eax = 0000000d ebx = 756e6547 ecx = 6c65746e edx = 49656e69
eax in: 0x00000001, eax = 000306c3 ebx = 00100800 ecx = 4ddaebbf edx = bfebfbff

Weitere Informationen dazu siehe auch FreeBSD Hardwareinformationen abfragen - x86info.

Intel stellt Informationen zu verfügbaren Microcode Versionen im Dokument Microcode Update Guidance bereit (siehe Intel Microcode - Microcode Versionen). In diesem Dokument werden CPUs anhand ihrer CPUID angeführt.

Bei einer Suche nach 306c3 im Dokument Microcode Update Guidance vom 08.08.2018 ist in der Spalte New Production MCU Rev die Microcode Version 0x25 angeführt. Intel stellt also in diesem Fall eine neuere Microcode Version bereit, als sie aktuell am Beispielsystem durch das BIOS vorhanden ist.

Variante 1: Update via devcpu-data

Der Port devcpu-data enthält Intel und AMD CPU Microcode Updates (Binärdateien). Die Microcodes von devcpu-data werden via cpuctl(4) / cpucontrol(8) in die CPU eingespielt. Damit die Aktualisierung des Microcodes automatisch beim Startvorgang durchgeführt wird, müssen in /boot/loader.conf die Einträge cpu_microcode_load und cpu_microcode_name ergänzt werden.

Um die Microcode Updates künftig automatisch einzuspielen, installieren Sie das Paket devcpu-data und tragen Sie anschließend die angeführten beiden Optionen in /boot/loader.conf ein:

# pkg install devcpu-data
# vi /boot/loader.conf
# cat /boot/loader.conf
cpu_microcode_load="YES"
cpu_microcode_name="/boot/firmware/intel-ucode.bin"
# reboot

Am Beispielsystem wird dadurch die Microcode Version von 0x24 auf 0x25 aktualisiert:

root@freebsd12:~ # pkg install devcpu-data
[...]
Message from devcpu-data-1.20:

Installing this port will allow host startup to update the CPU microcode on 
a FreeBSD system automatically.  There are two methods for updating CPU
microcode: the first methods loads and applies the update before the kernel
begins booting, and the second method loads and applies updates using an
rc script.  The first method is preferred, but is currently only supported
on Intel i386 and amd64 processors running FreeBSD 12.0.  It is safe to
enable both methods.

The first method ensures that any CPU features introduced by a microcode
update are visible to the kernel.  In other words, the update is loaded
before the kernel performs CPU feature detection.

To enable updates using the first method, add the following lines to
the system's /boot/loader.conf:

cpu_microcode_load="YES"
cpu_microcode_name="/boot/firmware/intel-ucode.bin"

This method will not load the microcode update until the system is
rebooted.

To enable updates using the second method, add the following line to
the system's /etc/rc.conf:

microcode_update_enable="YES"

Then, to ensure the update is applied, reboot the system or start the
microcode update service via:

# service microcode_update start

If the CPU requires a microcode update, a console message such as the following
will appear:

Updating CPU Microcode...
/usr/local/share/cpucontrol/m32306c3_00000022.fw: updating cpu /dev/cpuctl0 from rev 0x17 to rev 0x22... done.
/usr/local/share/cpucontrol/m32306c3_00000022.fw: updating cpu /dev/cpuctl2 from rev 0x17 to rev 0x22... done.
/usr/local/share/cpucontrol/m32306c3_00000022.fw: updating cpu /dev/cpuctl4 from rev 0x17 to rev 0x22... done.
/usr/local/share/cpucontrol/m32306c3_00000022.fw: updating cpu /dev/cpuctl6 from rev 0x17 to rev 0x22... done.
Done.
root@freebsd12:~ # ls -lh /boot/firmware/intel-ucode.bin
-rw-r--r--  1 root  wheel   1.7M Jan 11 23:18 /boot/firmware/intel-ucode.bin
root@freebsd12:~ # vi /boot/loader.conf
root@freebsd12:~ # cat /boot/loader.conf
cpu_microcode_load="YES"
cpu_microcode_name="/boot/firmware/intel-ucode.bin"
root@freebsd12:~ # reboot
[...]

Nach dem Reboot ist der neue Microcode im Einsatz:

root@freebsd12:~ # kldload cpuctl
root@freebsd12:~ # x86info -a | grep -i microcode
Microcode version: 0x0000000000000025

Variante 2: Update via cpupdate

Neben der oben beschriebenen Variante gibt es seit 2018 einen weiteren Port zum Aktualisieren des Microcodes: sysutils/cpupdate. Dieser wurde von Stefan Blachmann als Alternative zu zu devcpu-data entwickelt, um Bugs und Limitierungen von devcpu-data zu umgehen.[1][2][3] Das neue Tool cpupdate bietet zusätzliche Funktionen, z.B. die einfache Abfrage des aktuellen Microcodes via cpupdate -i.[4]

Der Entwickler empfiehlt, das Tool selbst zu kompilieren.[5] Da ein Upgrade von selbst-kompilierten Ports aufwändig ist,[6] empfiehlt sich auf Produktionssystemen eher die oben beschriebene #Variante 1 oder der Einsatz von poudriere zum Erstellen von Paketen aus Ports.

Die Installation von cpupdate auf einem Testsystem kann folgendermaßen erfolgen:

# portsnap auto
# cd /usr/ports/sysutils/cpupdate
# make install

Am Beispielsystem ausgeführt:

root@freebsd12:~ # portsnap auto
root@freebsd12:~ # cd /usr/ports
root@freebsd12:/usr/ports # make search name=cpupdate
Port:	cpupdate-g20180513_1
Path:	/usr/ports/sysutils/cpupdate
Info:	CPU microcode update utility for x86
Maint:	eugen@FreeBSD.org
B-deps:	
R-deps:	
WWW:	https://github.com/kernschmelze/cpupdate

root@freebsd12:/usr/ports # cd /usr/ports/sysutils/cpupdate
root@freebsd12:/usr/ports/sysutils/cpupdate # make install
===> Building/installing dialog4ports as it is required for the config dialog
[...]
                                          ┌─────────────────────────── cpupdate-g20180513_1 ─────────────────────────────┐
                                          │ ┌──────────────────────────────────────────────────────────────────────────┐ │  
                                          │ │+[x] CPM    Download platomav/CPUMicrocodes collection                    │ │  
                                          │ │+[x] INTEL  Download Intel microcode pack microcode-20180807.tgz          │ │  
                                          │ └──────────────────────────────────────────────────────────────────────────┘ │  
                                          ├──────────────────────────────────────────────────────────────────────────────┤  
                                          │                       <  OK  >            <Cancel>                           │  
                                          └──────────────────────────────────────────────────────────────────────────────┘  
===>  License BSD2CLAUSE accepted by the user
===>   cpupdate-g20180513_1 depends on file: /usr/local/sbin/pkg - found
=> microcode-20180807.tgz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch https://downloadmirror.intel.com/28039/eng/microcode-20180807.tgz
microcode-20180807.tgz                                1591 kB 7924 kBps    01s
[...]
Installing cpupdate-g20180513_1...
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NOTE: The following directories

/usr/ports/sysutils/cpupdate/work/CPUMicrocodes-0d88b2e
/usr/ports/sysutils/cpupdate/work/intel-ucode

contain Intel and/or platomav/CPUMicrocodes collections respectively
if you have just built the port with corresponding CPM/INTEL option(s) enabled.
In this case you can run "make install-microcodes" to install them to

/usr/local/share/cpupdate
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Suspend/resume sequence clears microcode update, so make sure your system runs
"service cpupdate start" again on resume.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

root@freebsd12:/usr/ports/sysutils/cpupdate # make install-microcodes
/bin/rm -f -rf /usr/local/share/cpupdate/CPUMicrocodes/primary/Intel
/bin/mkdir -p /usr/local/share/cpupdate/CPUMicrocodes/primary/Intel
[...]

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NOTE: you have to manually remove the directory
/usr/local/share/cpupdate/CPUMicrocodes/primary/Intel
after deinstallation of cpupdate.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NOTE: you have to manually remove the directory
/usr/local/share/cpupdate/CPUMicrocodes/secondary/Intel
after deinstallation of cpupdate.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
root@freebsd12:/usr/ports/sysutils/cpupdate #

Cpupdate bietet die folgenden Optionen:

# cpupdate 
Usage: cpupdate [-qwvvuiCXIAVh] [-<f|U> <microcodefile>] [-<cpsST> <datadir>]
  -i   show processor information
  -u   update microcode
  -U   update microcode using file <microcodefile>
  -w   write it: without this option cpupdate only simulates updating
  -q   quiet mode
  -v   verbose mode, -vv very verbose
  -p   use primary repo path <datadir>
  -s   use secondary repo path <datadir>
  -V   print version
  -h   show this help
  -IAV for the options below: vendor mode must be set [atm only Intel (-I) implemented]
  -f   show version information of microcode file
  -c   Check integrity of microcode files in <datadir>
  -d   As -c, in addition print microcode file statistics
  -C   convert/compact microcode files from legacy to multi-blob intel-ucode file format
  -X   convert (extract) microcode files from multi-blob intel-ucode to legacy file format
  -S   source dir for converting
  -T   target dir for converting

Die Aktualisierung des Microcodes zur Laufzeit sieht am Beispielsystem folgendermaßen aus:

root@freebsd12:/usr/ports/sysutils/cpupdate # cpupdate -i
Found CPU(s) from Intel
Core 0 to 1: CPUID: 306c3  Fam 06  Mod 3c  Step 03  Flag 02 uCode 00000024
root@freebsd12:/usr/ports/sysutils/cpupdate # cpupdate -u
Found CPU(s) from Intel
No updating error. Registering CPU features
Successfully registered new CPU features
ATTENTION NOTICE: -w option missing! No actual update, only dry run done!.
root@freebsd12:/usr/ports/sysutils/cpupdate # cpupdate -w -u
Found CPU(s) from Intel
No updating error. Registering CPU features
Successfully registered new CPU features
root@freebsd12:/usr/ports/sysutils/cpupdate # cpupdate -i
Found CPU(s) from Intel
Core 0 to 1: CPUID: 306c3  Fam 06  Mod 3c  Step 03  Flag 02 uCode 00000025
root@freebsd12:/usr/ports/sysutils/cpupdate #

Um den Microcode automatisch beim Starten zu aktualisieren, sind die folgenden Schritte erforderlich:

  1. Folgenden Eintrag in /boot/loader.conf ergänzen:
    cpuctl_load="YES"
  2. Folgenden Eintrag in in /etc/rc.conf ergänzen:
    cpupdate_enable="YES"
  3. Anschließend Reboot durchführen.

Nach dem Reboot zeigt cpupdate am Beispielsystem die neue Microcode-Version 0x25:

root@freebsd12:~ # cpupdate -i
Found CPU(s) from Intel
Core 0 to 1: CPUID: 306c3  Fam 06  Mod 3c  Step 03  Flag 02 uCode 00000025
root@freebsd12:~ # 

Unterschiede

Beim Testen der beiden Varianten fiel zum Testzeitpunkt am 16.01.2018 auf, dass bei der #Variante 1: Update via devcpu-data der Microcode bereits sehr früh während des Bootprozesses geladen wird.[7] Bereits bei der ersten Initialisierung der CPU werden die vier Structured Extended Features3 erkannt (IBPB,STIBP,L1DFL,SSBD), die durch die Microcode-Version 0x25 bereitgestellt werden. Hier der Auszug der dmesg Ausgabe dazu:

Copyright (c) 1992-2018 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
	The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 12.0-RELEASE-p2 GENERIC amd64
FreeBSD clang version 6.0.1 (tags/RELEASE_601/final 335540) (based on LLVM 6.0.1)
VT(efifb): resolution 800x600
CPU: Intel(R) Celeron(R) CPU G1820T @ 2.40GHz (2394.52-MHz K8-class CPU)
  Origin="GenuineIntel"  Id=0x306c3  Family=0x6  Model=0x3c  Stepping=3
[...]
  Structured Extended Features3=0x9c000000<IBPB,STIBP,L1DFL,SSBD>
[...]
real memory  = 2147483648 (2048 MB)
avail memory = 2002632704 (1909 MB)
CPU microcode: updated from 0x24 to 0x25

Bei der #Variante 2: Update via cpupdate fehlen zu Beginn noch zwei der vier Structured Extended Features 3 - somit ist zu Beginn noch die ältere Microcode Version 0x24 im Einsatz. Dies ist via dmesg ersichtlich:

Copyright (c) 1992-2018 The FreeBSD Project.
[...]
CPU: Intel(R) Celeron(R) CPU G1820T @ 2.40GHz (2394.52-MHz K8-class CPU)
  Origin="GenuineIntel"  Id=0x306c3  Family=0x6  Model=0x3c  Stepping=3
[...]
  Structured Extended Features3=0xc000000<IBPB,STIBP>
[...]
real memory  = 2147483648 (2048 MB)
[...]
Trying to mount root from ufs:/dev/ada0p2 [rw]...
CPU: Intel(R) Celeron(R) CPU G1820T @ 2.40GHz (2394.52-MHz K8-class CPU)
  Origin="GenuineIntel"  Id=0x306c3  Family=0x6  Model=0x3c  Stepping=3
[...]
  Structured Extended Features3=0x9c000000<IBPB,STIBP,L1DFL,SSBD>

Es ist mit #Variante 2: Update via cpupdate zwar auch möglich, den Microcode schon zu Beginn zu laden. Dazu muss allerdings die genaue Microcode-Datei der CPU angeführt werden.[8] Am Beispielsystem ist dies durch folgenden Eintrag in /boot/loader.conf möglich:

cpu_microcode_load="YES"
cpu_microcode_name="/usr/local/share/cpupdate/CPUMicrocodes/primary/Intel/06-3c-03"

Einzelnachweise

  1. Introducing cpupdate, a microcode tool for FreeBSD (forums.freebsd.org, 09.02.2018)
  2. cpupdate (github.com)
  3. Bug 192487 - cpucontrol uses unsafe procedure to detect current microcode version (bugs.freebsd.org)
  4. cpupdate manpage draft (bsd.denkverbot.info, 19.03.2018)
  5. cpupdate (github.com) Please do not install via pkg. Please use ports or manually clone it with git.
  6. Absolute FreeBSD 3rd Edition Chapter 16, page 371: Ports and Production: I would strongly encourage you to build build your own package repository with poudriere and manage your servers' ports from that repository. Upgrading ports directly installed on a host is annoying and difficult. [...] You have been warned.
  7. D16370: Implement early microcode loading for Intel i386 and amd64 platforms (reviews.freebsd.org)
  8. Introducing cpupdate, a microcode tool for FreeBSD - Comment #16 (forums.freebsd.org, 16.01.2019)


Foto Werner Fischer.jpg

Autor: Werner Fischer

Werner Fischer arbeitet im Product Management Team von Thomas-Krenn. Er evaluiert dabei neueste Technologien und teilt sein Wissen in Fachartikeln, bei Konferenzen und im Thomas-Krenn Wiki. Bereits 2005 - ein Jahr nach seinem Abschluss des Studiums zu Computer- und Mediensicherheit an der FH Hagenberg - heuerte er beim bayerischen Server-Hersteller an. Als Öffi-Fan nutzt er gerne Bus & Bahn und genießt seinen morgendlichen Spaziergang ins Büro.


Das könnte Sie auch interessieren

Broadcom VLAN Verbindungsproblem unter FreeBSD mit bnxt Treiber
FreeBSD aktualisieren
FreeBSD Broadcom Netzwerkkarten-Treiber aktivieren