From d613d88dd272cde8b69445bd69d64f99aac5b94b Mon Sep 17 00:00:00 2001 From: Jonas Witschel Date: Tue, 24 Dec 2019 15:48:19 +0100 Subject: [PATCH] ucode: use microcode found in packed cpio images 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 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/dracut.sh b/dracut.sh index 06c751dc..f44b6b47 100755 --- 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