]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
ucode: use microcode found in packed cpio images
authorJonas Witschel <diabonas@gmx.de>
Tue, 24 Dec 2019 14:48:19 +0000 (15:48 +0100)
committerHarald Hoyer <harald@hoyer.xyz>
Fri, 24 Jan 2020 08:06:32 +0000 (09:06 +0100)
Some distributions (Arch, Gentoo) ship prepacked microcode images. These
are cpio images that follow the structure specified in the Linux kernel
documentation (x86/microcode.rst, "Early load microcode"), the same
structure dracut uses for its early microcode images.

In case of Arch Linux, the microcode for Intel CPUs is currently only
available in this packed form, /usr/lib/firmware/intel-ucode does not
exist. This commit adds a way to make use of these images on such
systems by unpacking them to the early cpio directory. (Note that the
packed image cannot be used directly since dracut might need to add ACPI
tables to the early initramfs.)

This approach has the drawback that it is not possible to control the
selection of CPUs to be included in the microcode file in host-only
mode, so we only try it as a last ressort if no unpacked microcode could
be found in fw_dir.

The list of possible file names for the packed microcode image is taken
from GRUB (cf. GRUB_EARLY_INITRD_LINUX_STOCK), but can be adapted by
setting "early_microcode_image_name" (and "early_microcode_image_dir")
in a dracut configuration file.

dracut.sh

index 06c751dce09d6b64f59c8fc1c199914f1a926edb..f44b6b471509775c93e5adfd19c7de607b38b274 100755 (executable)
--- a/dracut.sh
+++ b/dracut.sh
@@ -765,6 +765,9 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
 [[ $ro_mnt_l ]] && ro_mnt="yes"
 [[ $early_microcode_l ]] && early_microcode=$early_microcode_l
 [[ $early_microcode ]] || early_microcode=yes
+[[ $early_microcode_image_dir ]] || early_microcode_image_dir=('/boot')
+[[ $early_microcode_image_name ]] || \
+    early_microcode_image_name=('intel-uc.img' 'intel-ucode.img' 'amd-uc.img' 'amd-ucode.img' 'early_ucode.cpio' 'microcode.cpio')
 [[ $logfile_l ]] && logfile="$logfile_l"
 [[ $reproducible_l ]] && reproducible="$reproducible_l"
 [[ $loginstall_l ]] && loginstall="$loginstall_l"
@@ -1737,6 +1740,21 @@ if [[ $early_microcode = yes ]]; then
                 create_early_cpio="yes"
             fi
         done
+        if [[ ! -e "$_dest_dir/${ucode_dest[$idx]}" ]]; then
+            cd "$early_cpio_dir/d"
+            for _ucodedir in "${early_microcode_image_dir[@]}"; do
+                for _ucodename in "${early_microcode_image_name[@]}"; do
+                    [[ -e "$_ucodedir/$_ucodename" ]] && \
+                    cpio --extract --file "$_ucodedir/$_ucodename" --quiet \
+                         "kernel/x86/microcode/${ucode_dest[$idx]}"
+                    if [[ -e "$_dest_dir/${ucode_dest[$idx]}" ]]; then
+                        dinfo "*** Using microcode found in '$_ucodedir/$_ucodename' ***"
+                        create_early_cpio="yes"
+                        break 2
+                    fi
+                done
+            done
+        fi
     done
 fi