Aktualizacja mikrokodu procesorów firmy Intel w FreeBSD

Z Thomas-Krenn-Wiki
Przejdź do nawigacji Przejdź do wyszukiwania

FreeBSD umożliwia aktualizację mikrokodu procesora na etapie uruchamiania lub w czasie działania systemu. W tym artykule, korzystając z serwera z FreeBSD 12.0, chcemy pokazać, jak można sprawdzić aktualną wersję mikrokodu firmy Intel i w razie potrzeby zainstalować nowszą wersję mikrokodu.

Konfiguracja testowa

W tym przykładzie została wykorzystana następująca konfiguracja:

Poniższy przykład został przeprowadzony 16.01.2019 r. z aktualnymi w tym czasie wersjami BIOS-u, mikrokodu i oprogramowania. Przedstawia on, jak w środowiskach o krytycznym znaczeniu dla bezpieczeństwa może zostać przeprowadzona aktualizacja mikrokodu i aktualizacje bezpieczeństwa.

Odczyt aktualnej wersji mikrokodu

W Microcode Update Guidance z 08.08.2018 (vide MICROCODE REVISION GUIDANCE) jest podana nowa wersja mikrokodu 0x25, dla wykorzystanego w tym przykładzie procesora Intel Celeron G1820T (CPUID 306c3).

Informacje o CPU (nazwa, CPUID, wersja mikrokodu) można uzyskać za pomocą narzędzia x86info po załadowaniu modułu cpuctl:

kldload cpuctl
x86info -a

W wierszu Microcode version jest widoczna wersja (w przykładzie 0x00000000000000000024), CPUID znajduje się w drugim wierszu eax (w przykładzie 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

Więcej informacji na ten temat można znaleźć na stronie Odczyt informacji o sprzęcie w FreeBSD - x86info.

Intel udostępnia informacje o dostępnych wersjach mikrokodu w dokumencie Microcode Update Guidance ( vide Intel Microcode - wersje mikrokodu). W tym dokumencie procesory są wymienione według CPUID.

Szukając 306c3 w Microcode Update Guidance z 08.08.2018, w kolumnie New Production MCU Rev znajduje się mikrokod w wersji 0x25. W tym przypadku Intel dostarcza nowszą wersję mikrokodu niż obecnie dostępna w BIOS-ie testowego systemu.

Wariant 1: Update via devcpu-data

Port devcpu-data zawiera aktualizacje mikrokodów dla procesorów Intel i AMD (pliki binarne). Mikrokody z devcpu-data są wprowadzane do procesora poprzez cpuctl(4) / cpucontrol(8). Aby aktualizacja mikrokodu była przeprowadzana automatycznie podczas uruchamiania, wpisy cpu_microcode_load i cpu_microcode_name muszą zostać dodane do /boot/loader.conf.

Aby w przyszłości automatycznie instalować aktualizacje mikrokodu, należy zainstalować pakiet devcpu-data i następnie wprowadzić dwie wymienione opcje w /boot/loader.conf:

# 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

Na testowym systemie, wersja mikrokodu jest aktualizowana z 0x24 do 0x25:

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
[...]

Po ponownym uruchomieniu systemu nowy mikrokod jest już używany:

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

Wariant 2: Update via cpupdate

Oprócz wariantu opisanego powyżej, od 2018 r. dostępny jest jeszcze jeden port do aktualizacji mikrokodu: sysutils/cpupdate. Został on opracowany przez Stefana Blachmanna jako alternatywa dla devcpu-data, aby uniknąć błędów i ograniczeń devcpu-data.[1][2][3] Nowe narzędzie cpupdate oferuje dodatkowe funkcje, np. proste uzyskanie informacji o aktualnym mikrokodzie poprzez cpupdate -i.[4]

Twórca zaleca samodzielne skompilowanie narzędzia.[5] Ponieważ modernizacja z skompilowanych portów jest żmudna,[6] Z racji tego, że upgrade z kompilowanych portów jest pracochłonny,[7] na systemach produkcyjnych jest bardziej zalecane użycie opisanego powyżej wariantu 1 lub użycie poudriere do budowania pakietów z portów.

Instalacja cpupdate na systemie testowym może być wykonana w następujący sposób:

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

Wykonane na systemie testowym:

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 oferuje następujące opcje:

# 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

Aktualizacja mikrokodu podczas pracy wygląda następująco na przykładowym systemie:

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 #

W celu automatycznej aktualizacji mikrokodu przy uruchamianiu wymagane są następujące kroki:

  1. Należy dodać następujący wpis do /boot/loader.conf:
    cpuctl_load="YES"
  2. Dodajemy następujący wpis do /etc/rc.conf:
    cpupdate_enable="YES"
  3. Następnie należy wykonać restart.

Po ponownym uruchomieniu cpupdate pokazuje na przykładowym systemie nową wersję mikrokodu 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:~ # 

Różnice

Podczas testowania obydwu wariantów w dniu 16.01.2018, zauważyliśmy, że #Wariant 1: Update via devcpu-data ładuje mikrokod bardzo wcześnie już w trakcie procesu uruchamiania.[8] Już przy pierwszej inicjalizacji procesora rozpoznawane są cztery Structured Extended Features3, (IBPB, STIBP, L1DFL, SSBD), które są zawarte w wersji mikrokodu 0x25. Oto fragment wyjścia z dmesg:

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

W wariancie 2 z cpupdate brakuje na początku dwóch z czterech Structured Extended Features 3 - dlatego starsza wersja mikrokodu 0x24 jest nadal na początku w użyciu. Jest to widoczne w dmesg:

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>

Wprawdzie w wariancie 2 z cpupdate również możliwe jest wczytanie mikrokodu już na początku, jednak w tym celu należy podać dokładny plik mikrokodu procesora.[9] W przykładowym systemie, jest to możliwe dzięki następującej pozycji w /boot/loader.conf:

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

Odnośniki

  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. 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.
  8. D16370: Implement early microcode loading for Intel i386 and amd64 platforms (reviews.freebsd.org)
  9. Introducing cpupdate, a microcode tool for FreeBSD - Comment #16 (forums.freebsd.org, 16.01.2019)

Autor: Werner Fischer

Powiązane artykuły

Odczyt informacji o sprzęcie w FreeBSD
Uaktualnienie systemu FreeBSD