マイクロコード
プロセッサの製造者はプロセッサマイクロコードに安定性とセキュリティのアップデートをリリースしています。そのようなアップデートには、システムの安定性に深く関わるバグフィックスが含まれています。これがないと、追跡困難な疑わしいクラッシュや予期しないシステム停止を引き起こす場合があります。
AMD や Intel CPU を持つすべてのユーザは、システムの安定性を確保するためにマイクロコードのアップデートをインストールすべきです。仮想マシンやコンテナ内では、マイクロコードのアップデートはゲストシステムではなく、ホストに属します。
目次
マイクロコードをロードする
通常、マイクロコードのアップデートはマザーボードのファームウェアに同梱されており、ファームウェアの初期化中に適用されます。しかし、OEM はファームウェアのアップデートをタイムリーにリリースしないかもしれない上、古いシステムでは新しいファームウェアアップデートは全くリリースされないので、起動中に CPU マイクロコードアップデートを適用する機能が Linux カーネルに追加されました。Linux マイクロコードローダは3つの方法をサポートします:
- 組み込みマイクロコード は、カーネルに組み込んでコンパイルし、早期ローダ (early loader) を使って適用することができます。
- 早期ロード は、起動中の非常に早い段階 (initramfs ステージよりも前) でマイクロコードをアップデートします。遅延ロードよりもこちらが推奨されます。Intel の Haswell や Broadwell プロセッサファミリのように CPU に深刻なハードウェアバグが存在する場合、早期ロードが必須です。
- 遅延ロード (危険) は、起動後にマイクロコードをアップデートします。CPU が欠陥のある命令の使用をすでに試みたかもしれないので、これでは遅すぎる可能性があります。「早期ロード」をすでに使用している場合でも、「遅延ロード」を使用して再起動せずに新しいマイクロコードのアップデートを適用できます。
更新されたマイクロコードを取得するには、プロセッサに応じて以下のいずれかのパッケージをインストールしてください:
- amd-ucode : AMD プロセッサ
- intel-ucode : Intel プロセッサ
initramfs に埋め込まれたマイクロコード
マイクロコード cpio を initramfs 内部に前置することができます。dracut など (dracut.conf(5) § DESCRIPTION を参照) の一部の initramfs ジェネレータは、これをデフォルトで行います。これにより、#早期ロード と #遅延ロード は不要になります。しかし、Arch Linux はデフォルトで初期 RAM ディスク (initramfs) の生成に mkinitcpio を使用し、mkinitcpio はこの方法をサポートしていません。しかし、UEFI スタブを用いたマイクロコードの読み込みはサポートしています: #Unified カーネルイメージ を見てください。
早期ロード
マイクロコードは、カーネルに組み込まない場合、初期ローダ (early loader) を使って読み込まなければなりません。Unified カーネルイメージの一部として、あるいは ブートローダーを使って初期 RAM ディスクイメージとしてローダに渡すことができます。
ユーザの初期ブート構成は様々なので、マイクロコードのアップデートは Arch のデフォルトの設定では自動的にトリガーされないことに注意してください。
Unified カーネルイメージ
Unified カーネルイメージ の記事で、単一ファイルのイメージにマイクロコードを埋め込む方法を見てください。
初期 RAM ディスクイメージ
あるいは、マイクロコードのアップデートを有効にするには、/boot/amd-ucode.img
または /boot/intel-ucode.img
をブートローダーの設定ファイルの 一番目の初期 RAM ディスクイメージ として追加しなければなりません。これは、通常の初期 RAM ディスクイメージファイルよりも前です。一般的なブートローダの場合における手順は以下を見てください。
以下のセクションでは cpu_manufacturer
の部分をあなたの CPU の製造業者名に置き換えてください、例: amd
か intel
。
カスタムカーネルでマイクロコードの早期ロードを有効化
カスタムカーネルでロードを行うには、"CPU microcode loading support" をカーネルに組み込む必要があります。モジュールとしてコンパイルしても動作しません。"Early load microcode" プロンプトが有効になるので "Y" に設定してください。
CONFIG_BLK_DEV_INITRD=Y CONFIG_MICROCODE=y CONFIG_MICROCODE_INTEL=Y CONFIG_MICROCODE_AMD=y
GRUB
grub-mkconfig はマイクロコードのアップデートを自動的に検出し、GRUB を適切に設定します。マイクロコードのインストール後に以下を実行して GRUB 設定ファイルを再生成し、マイクロコードアップデートのロードを有効化してください:
# grub-mkconfig -o /boot/grub/grub.cfg
あるいは、GRUB 設定ファイルを手動で管理しているユーザは、以下のように /boot/cpu_manufacturer-ucode.img
を追加できます(別のパーティションに /boot
がある場合は /cpu_manufacturer-ucode.img
):
/boot/grub/grub.cfg
... echo 'Loading initial ramdisk' initrd /boot/cpu_manufacturer-ucode.img /boot/initramfs-linux.img ...
それぞれのメニュエントリに対してこれを行ってください。
systemd-boot
以下のように初期 RAM ディスクの前に initrd
オプションを使ってマイクロコードをロード:
/boot/loader/entries/entry.conf
title Arch Linux linux /vmlinuz-linux initrd /cpu_manufacturer-ucode.img initrd /initramfs-linux.img ...
最新のマイクロコード cpu_manufacturer-ucode.img
は起動時に EFI システムパーティション (ESP) に存在していなければなりません。amd-ucode または intel-ucode を更新したときはマイクロコードが更新されるように /boot
に ESP をマウントしてください。もしくは、マイクロコードパッケージのアップデートがあるたびに ESP に /boot/cpu_manufacturer-ucode.img
をコピーしてください。
EFISTUB
2つの initrd=
オプションを末尾に追加してください:
initrd=\cpu_manufacturer-ucode.img initrd=\initramfs-linux.img
rEFInd
/boot/refind_linux.conf
のブートオプションを編集し、マイクロコードイメージをロードするための initrd=
オプションを最初の initrd
引数として追加してください。/boot
内のファイルが別のパーティションの直下にあるかどうかに応じて、initrd=boot\cpu_manufacturer-ucode.img
か initrd=cpu_manufacturer-ucode.img
のどちらかを使ってください。
マイクロコードは、ブートオプションのリストの中で最初に宣言された initramfs でなければなりません。例えば:
"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"
手動でブートオプションを記述する
手動で esp/EFI/refind/refind.conf
にカーネルを定義している場合は、initrd=
パラメータを追加して、ブートパーティション内の適切なパスに設定する必要があります。このパラメータは options 行の一部である必要があり、設定のメインの部分ではありません。例:
options "root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw add_efi_memmap initrd=boot\cpu_manufacturer-ucode.img"
Syslinux
/boot/syslinux/syslinux.cfg
で複数の initrd をカンマで区切って指定できます:
LABEL arch MENU LABEL Arch Linux LINUX ../vmlinuz-linux INITRD ../cpu_manufacturer-ucode.img,../initramfs-linux.img ...
LILO
LILO などの旧式のブートローダーは複数の initrd イメージをサポートしていません。そのような場合 cpu_manufacturer-ucode.img
と initramfs-linux.img
をひとつのイメージにまとめる必要があります。
ふたつのイメージを initramfs-merged.img
という名前のイメージにマージするには、以下のコマンドを使用:
# cat /boot/cpu_manufacturer-ucode.img /boot/initramfs-linux.img > /boot/initramfs-merged.img
マージできたら /etc/lilo.conf
を編集して新しいイメージをロードします:
... initrd=/boot/initramfs-merged.img ...
root で lilo
を実行してください:
# lilo
Limine
Limine においては、limine.cfg ファイル内の MODULE_PATH
オプションにマイクロコードへのパスを追加するだけで良いです。以下は例です:
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
遅延ロード
マイクロコードアップデートの遅延ロードはシステムの起動後に行われます。/usr/lib/firmware/amd-ucode/
と /usr/lib/firmware/intel-ucode/
内のファイルが使用されます。Linux 5.19 以降で遅延ロードを行うには、CONFIG_MICROCODE_LATE_LOADING=y
でカーネルをビルドする必要があります。
AMD プロセッサの場合、マイクロコードのアップデートファイルは linux-firmware により提供されます。
Intel プロセッサの場合、マイクロコードのアップデートファイルが含まれるパッケージはありません (FS#59841)。遅延ロードするには Intel が提供しているアーカイブから手動で intel-ucode/
を抽出する必要があります。
マイクロコードの遅延アップデートを有効化
早期ロードとは異なり、マイクロコードアップデートの遅延ロードは Arch Linux ではデフォルトで有効になっており /usr/lib/tmpfiles.d/linux-firmware.conf
を使用します。起動後に systemd-tmpfiles-setup.service(8) によってファイルが読み込まれて CPU のマイクロコードが更新されます。
実行中のシステムで手動でマイクロコードをアップデートするには(例: /usr/lib/firmware/amd-ucode/
か /usr/lib/firmware/intel-ucode/
内のマイクロコードファイルをアップデートした後):
# echo 1 > /sys/devices/system/cpu/microcode/reload
これにより、システムを再起動せずに新しいマイクロコードのアップデートを適用できます。
マイクロコードの遅延アップデートを無効化
AMD 環境では amd-ucode がインストールされてなくても、/usr/lib/firmware/amd-ucode/
内のファイルが linux-firmware パッケージにより提供されるため、CPU のマイクロコードはアップデートされてしまいます (FS#59840)。
仮想マシンとコンテナでは(FS#46591)、CPU のマイクロコードをアップできません。なので、マイクロコードのアップデートを無効化したほうが良いでしょう。
マイクロコードの危険な遅延ロードを無効にしたい場合、linux-firmware により提供される /usr/lib/tmpfiles.d/linux-firmware.conf
tmpfile を上書きしてください。/etc/tmpfiles.d/
に同名のファイルを作成することで無効化できます:
# ln -s /dev/null /etc/tmpfiles.d/linux-firmware.conf
起動時にマイクロコードのアップデートがされたか確認する
マイクロコードがアップデートされたかどうか確認するには journalctl でカーネルメッセージを確認してください:
# journalctl -k --grep=microcode
Intel が載っているシステムでは、起動時に以下のような表示がされます(以下ではマイクロコードが非常に早い段階でアップデートされていることを示しています):
microcode: microcode updated early to revision 0xde, date = 2020-05-18 microcode: sig=0x806ec, pf=0x80, revision=0xde microcode: Microcode Update Driver: v2.2.
最新のハードウェアの場合、CPU のマイクロコードアップデートが存在しないという可能性も考えられます。そのときは、以下のような出力がなされます:
microcode: sig=0x806ec, pf=0x80, revision=0xde microcode: Microcode Update Driver: v2.2.
AMD 環境でマイクロコードを早期ロードしている場合、以下のように出力されます:
microcode: microcode updated early to new patch_level=0x0700010f 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.
AMD 環境で起動後にマイクロコードをアップデートしている場合、古いマイクロコードのバージョンが表示されてからマイクロコードがリロードされ、新しいマイクロコードのバージョンが表示されます。例:
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.
マイクロコードのアップデートができる CPU
特定のモデルがサポートされているのかどうかは以下のリンクから Intel のサイトや AMD の Gentoo Wiki サイトで確認することができます:
マイクロコードのアップデートが必要かどうか確認する
iucode-tool を使って、使用している CPU のマイクロコードイメージが intel-ucode.img
に含まれているかどうか確認できます。
- intel-ucode をインストール (アップデートがあるかどうか確認するのに initrd の変更は必要ありません)
- iucode-tool をインストール
cpuid
カーネルモジュールをロード:# modprobe cpuid
- マイクロコードイメージを展開して cpuid で検索:
# bsdtar -Oxf /boot/intel-ucode.img | iucode_tool -tb -lS -
- アップデートが存在する場合は、selected microcodes の下に表示されます。
- メーカーの BIOS にマイクロコードが既に含まれていてロードされたことが dmesg に表示されていない可能性もあります。
grep microcode /proc/cpuinfo
を実行して現在のマイクロコードを比較してください。