microcode_ctl/dracut_99microcode_ctl-fw_dir_override_module_init.sh
Eugene Syromiatnikov dc2b22a876 dracut_99microcode_ctl-fw_dir_override_module_init.sh: add new default fw_dir
Since commit dracut-57~5[1], dracut uses a different set directories
as default $fw_dir, which leads to not resetting it to a state where
kernel-based FW directories (where the microcode for late load resides)
are skipped and leads to having multiple microcode versions in the early
cpio, which prevents the caveats mechanism from working properly.

[1] https://github.com/dracutdevs/dracut/commit/95aeed8975dd

* dracut_99microcode_ctl-fw_dir_override_module_init.sh: Check $fw_dir
for the new default directory set as well in the condition
for the $fw_dir reset check.
* microcode_ctl.spec (Release): Bump to 2.
(%changelog): Add a new record.

Resolves: #2213125
Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-08-23 09:02:05 +02:00

138 lines
4.0 KiB
Bash
Executable File

#!/bin/bash
# Hack in additional firmware directories for supported caveats.
#
# SPDX-License-Identifier: CC0-1.0
check() {
return 0
}
install() {
local FW_DIR=/lib/firmware
local DATA_DIR=/usr/share/microcode_ctl/ucode_with_caveats
local CFG_DIR="/etc/microcode_ctl/ucode_with_caveats"
local check_caveats=/usr/libexec/microcode_ctl/check_caveats
local fw_path_para=$(< /sys/module/firmware_class/parameters/path)
local verbose_opt
local cc_out
local path
local ignored
local do_skip_host_only
local p
verbose_opt=
[ 4 -gt "$stdloglvl" ] || verbose_opt="-v"
# HACK: we override external fw_dir variable in order to get
# an additional ucode based on the kernel version.
dinfo " microcode_ctl module: mangling fw_dir"
[ -z "$fw_dir_l" ] || {
dinfo " microcode_ctl: avoid touching fw_dir as" \
"it has been changed (fw_dir_l is '$fw_dir_l')"
return 0
}
# Reset fw_dir to avoid inclusion of kernel-version-specific directories
# populated with microcode for the late load, only in case it is set
# to the default value to avoid meddling with user-enforced changes.
# The second variant has been introduced in dracut-057~5.
[ \( "x$fw_dir" != \
"x/lib/firmware/updates /lib/firmware /lib/firmware/$kernel" \) -a \
\( "x$fw_dir" != \
"x${fw_path_para:+$fw_path_para }/lib/firmware/updates/$kernel /lib/firmware/updates /lib/firmware/$kernel /lib/firmware" \) ] || {
fw_dir="/lib/firmware/updates /lib/firmware"
dinfo " microcode_ctl: reset fw_dir to \"${fw_dir}\""
}
fw_dir_add=""
while read -d $'\n' -r i; do
dinfo " microcode_ctl: processing data directory " \
"\"$DATA_DIR/$i\"..."
if [ "x" != "x$hostonly" ]; then
do_skip_host_only=0
local sho_overrides="
$CFG_DIR/skip-host-only-check
$CFG_DIR/skip-host-only-check-$i
$FW_DIR/$kernel/skip-host-only-check
$FW_DIR/$kernel/skip-host-only-check-$i"
for p in $(echo "$sho_overrides"); do
[ -e "$p" ] || continue
do_skip_host_only=1
dinfo " microcode_ctl: $i; skipping" \
"Host-Only check, since \"$p\" exists."
break
done
else
do_skip_host_only=1
fi
match_model_opt=""
[ 1 = "$do_skip_host_only" ] || match_model_opt="-m"
if ! cc_out=$($check_caveats -e -k "$kernel" -c "$i" \
$verbose_opt $match_model_opt)
then
dinfo " microcode_ctl: kernel version \"$kernel\"" \
"failed early load check for \"$i\", skipping"
continue
fi
path=$(printf "%s" "$cc_out" | sed -n 's/^paths //p')
[ -n "$path" ] || {
ignored=$(printf "%s" "$cc_out" | \
sed -n 's/^skip_cfgs //p')
if [ -n "$ignored" ]; then
dinfo " microcode_ctl: configuration" \
"\"$i\" is ignored"
else
dinfo " microcode_ctl: no microcode paths" \
"are associated with \"$i\", skipping"
fi
continue
}
dinfo " microcode_ctl: $i: caveats check for kernel" \
"version \"$kernel\" passed, adding" \
"\"$DATA_DIR/$i\" to fw_dir variable"
if [ 0 -eq "$do_skip_host_only" ]; then
fw_dir_add="$DATA_DIR/$i "
else
fw_dir_add="$DATA_DIR/$i $fw_dir_add"
fi
# The list of directories is reverse-sorted in order to preserve the
# "last wins" policy in case of presence of multiple microcode
# revisions.
#
# In case of hostonly == 0, all microcode revisions will be included,
# but since the microcode search is done with the "first wins" policy
# by the (early) microcode loading code, the correct microcode revision
# still has to be picked.
#
# Note that dracut without patch [1] puts only the last directory
# in the early cpio; we try to address this by putting only the last
# matching caveat in the search path, but that workaround works only
# for host-only mode; non-host-only mode early cpio generation is still
# broken without that patch.
#
# [1] https://github.com/dracutdevs/dracut/commit/c44d2252bb4b
done <<-EOF
$(find "$DATA_DIR" -maxdepth 1 -mindepth 1 -type d -printf "%f\n" \
| LC_ALL=C sort)
EOF
fw_dir="${fw_dir_add}${fw_dir}"
dinfo " microcode_ctl: final fw_dir: \"${fw_dir}\""
}