|
|
b24a43 |
#!/bin/bash
|
|
|
b24a43 |
|
|
|
b24a43 |
# Hack in additional firmware directories for supported caveats.
|
|
|
b24a43 |
#
|
|
|
b24a43 |
# SPDX-License-Identifier: CC0-1.0
|
|
|
b24a43 |
|
|
|
b24a43 |
check() {
|
|
|
b24a43 |
return 0
|
|
|
b24a43 |
}
|
|
|
b24a43 |
|
|
|
b24a43 |
install() {
|
|
|
b24a43 |
local FW_DIR=/lib/firmware
|
|
|
b24a43 |
local DATA_DIR=/usr/share/microcode_ctl/ucode_with_caveats
|
|
|
b24a43 |
local CFG_DIR="/etc/microcode_ctl/ucode_with_caveats"
|
|
|
b24a43 |
local check_caveats=/usr/libexec/microcode_ctl/check_caveats
|
|
|
b24a43 |
|
|
|
b24a43 |
local verbose_opt
|
|
|
b24a43 |
local cc_out
|
|
|
b24a43 |
local path
|
|
|
b24a43 |
local ignored
|
|
|
b24a43 |
local do_skip_host_only
|
|
|
b24a43 |
local p
|
|
|
b24a43 |
|
|
|
b24a43 |
verbose_opt=
|
|
|
b24a43 |
[ 4 -gt "$stdloglvl" ] || verbose_opt="-v"
|
|
|
b24a43 |
|
|
|
b24a43 |
# HACK: we override external fw_dir variable in order to get
|
|
|
b24a43 |
# an additional ucode based on the kernel version.
|
|
|
b24a43 |
dinfo " microcode_ctl module: mangling fw_dir"
|
|
|
b24a43 |
|
|
|
b24a43 |
[ -z "$fw_dir_l" ] || {
|
|
|
b24a43 |
dinfo " microcode_ctl: avoid touching fw_dir as" \
|
|
|
b24a43 |
"it has been changed (fw_dir_l is '$fw_dir_l')"
|
|
|
b24a43 |
|
|
|
b24a43 |
return 0
|
|
|
b24a43 |
}
|
|
|
b24a43 |
|
|
|
b24a43 |
# Reset fw_dir to avoid inclusion of kernel-version-specific directories
|
|
|
b24a43 |
# populated with microcode for the late load
|
|
|
b24a43 |
[ "x$fw_dir" != \
|
|
|
b24a43 |
"x/lib/firmware/updates /lib/firmware /lib/firmware/$kernel" ] || {
|
|
|
b24a43 |
fw_dir="/lib/firmware/updates /lib/firmware"
|
|
|
b24a43 |
dinfo " microcode_ctl: reset fw_dir to \"${fw_dir}\""
|
|
|
b24a43 |
}
|
|
|
b24a43 |
|
|
|
edc2a6 |
fw_dir_add=""
|
|
|
edc2a6 |
while read -d $'\n' -r i; do
|
|
|
b24a43 |
dinfo " microcode_ctl: processing data directory " \
|
|
|
b24a43 |
"\"$DATA_DIR/$i\"..."
|
|
|
b24a43 |
|
|
|
b24a43 |
if ! cc_out=$($check_caveats -e -k "$kernel" -c "$i" $verbose_opt)
|
|
|
b24a43 |
then
|
|
|
b24a43 |
dinfo " microcode_ctl: kernel version \"$kernel\"" \
|
|
|
b24a43 |
"failed early load check for \"$i\", skipping"
|
|
|
b24a43 |
continue
|
|
|
b24a43 |
fi
|
|
|
b24a43 |
|
|
|
b24a43 |
path=$(printf "%s" "$cc_out" | sed -n 's/^paths //p')
|
|
|
b24a43 |
[ -n "$path" ] || {
|
|
|
b24a43 |
ignored=$(printf "%s" "$cc_out" | \
|
|
|
b24a43 |
sed -n 's/^skip_cfgs //p')
|
|
|
b24a43 |
|
|
|
b24a43 |
if [ -n "$ignored" ]; then
|
|
|
b24a43 |
dinfo " microcode_ctl: configuration" \
|
|
|
b24a43 |
"\"$i\" is ignored"
|
|
|
b24a43 |
else
|
|
|
b24a43 |
dinfo " microcode_ctl: no microcode paths" \
|
|
|
b24a43 |
"are associated with \"$i\", skipping"
|
|
|
b24a43 |
fi
|
|
|
b24a43 |
|
|
|
b24a43 |
continue
|
|
|
b24a43 |
}
|
|
|
b24a43 |
|
|
|
b24a43 |
if [ "x" != "x$hostonly" ]; then
|
|
|
b24a43 |
do_skip_host_only=0
|
|
|
b24a43 |
|
|
|
b24a43 |
local sho_overrides="
|
|
|
b24a43 |
$CFG_DIR/skip-host-only-check
|
|
|
b24a43 |
$CFG_DIR/skip-host-only-check-$i
|
|
|
b24a43 |
$FW_DIR/$kernel/skip-host-only-check
|
|
|
b24a43 |
$FW_DIR/$kernel/skip-host-only-check-$i"
|
|
|
b24a43 |
|
|
|
b24a43 |
for p in $(echo "$sho_overrides"); do
|
|
|
b24a43 |
[ -e "$p" ] || continue
|
|
|
b24a43 |
|
|
|
b24a43 |
do_skip_host_only=1
|
|
|
b24a43 |
dinfo " microcode_ctl: $i; skipping" \
|
|
|
b24a43 |
"Host-Only check, since \"$p\" exists."
|
|
|
b24a43 |
break
|
|
|
b24a43 |
done
|
|
|
b24a43 |
else
|
|
|
b24a43 |
do_skip_host_only=1
|
|
|
b24a43 |
fi
|
|
|
b24a43 |
|
|
|
b24a43 |
if [ 0 -eq "$do_skip_host_only" ]; then
|
|
|
b24a43 |
local hostonly_passed=0
|
|
|
b24a43 |
local ucode
|
|
|
b24a43 |
local uvendor
|
|
|
b24a43 |
local ucode_dir=""
|
|
|
b24a43 |
|
|
|
b24a43 |
ucode=$(get_ucode_file)
|
|
|
b24a43 |
uvendor=$(get_cpu_vendor)
|
|
|
b24a43 |
|
|
|
b24a43 |
case "$uvendor" in
|
|
|
b24a43 |
Intel)
|
|
|
b24a43 |
ucode_dir="intel-ucode"
|
|
|
b24a43 |
;;
|
|
|
b24a43 |
AMD)
|
|
|
c08efc |
ucode_dir="amd-ucode"
|
|
|
b24a43 |
;;
|
|
|
b24a43 |
*)
|
|
|
b24a43 |
dinfo " microcode_ctl: unknown CPU" \
|
|
|
b24a43 |
"vendor: \"$uvendor\", bailing out of" \
|
|
|
b24a43 |
"Host-Only check"
|
|
|
b24a43 |
continue
|
|
|
b24a43 |
;;
|
|
|
b24a43 |
esac
|
|
|
b24a43 |
|
|
|
b24a43 |
# $path is a list of globs, so it needs special care
|
|
|
b24a43 |
for p in $(printf "%s" "$path"); do
|
|
|
b24a43 |
find "$DATA_DIR/$i" -path "$DATA_DIR/$i/$p" \
|
|
|
b24a43 |
-print0 \
|
|
|
b24a43 |
| grep -zFxq \
|
|
|
b24a43 |
"$DATA_DIR/$i/$ucode_dir/$ucode" \
|
|
|
b24a43 |
|| continue
|
|
|
b24a43 |
|
|
|
b24a43 |
dinfo " microcode_ctl: $i: Host-Only" \
|
|
|
b24a43 |
"mode is enabled and" \
|
|
|
b24a43 |
"\"$ucode_dir/$ucode\" matches \"$p\""
|
|
|
b24a43 |
|
|
|
b24a43 |
hostonly_passed=1
|
|
|
b24a43 |
break
|
|
|
b24a43 |
done
|
|
|
b24a43 |
|
|
|
b24a43 |
[ 1 -eq "$hostonly_passed" ] || {
|
|
|
b24a43 |
dinfo " microcode_ctl: $i: Host-Only mode" \
|
|
|
b24a43 |
"is enabled and ucode name does not" \
|
|
|
b24a43 |
"match the expected one, skipping" \
|
|
|
b24a43 |
"caveat (\"$ucode\" not in \"$path\")"
|
|
|
b24a43 |
continue
|
|
|
b24a43 |
}
|
|
|
b24a43 |
fi
|
|
|
b24a43 |
|
|
|
b24a43 |
dinfo " microcode_ctl: $i: caveats check for kernel" \
|
|
|
b24a43 |
"version \"$kernel\" passed, adding" \
|
|
|
b24a43 |
"\"$DATA_DIR/$i\" to fw_dir variable"
|
|
|
c08efc |
|
|
|
edc2a6 |
if [ 0 -eq "$do_skip_host_only" ]; then
|
|
|
edc2a6 |
fw_dir_add="$DATA_DIR/$i "
|
|
|
edc2a6 |
else
|
|
|
edc2a6 |
fw_dir_add="$DATA_DIR/$i $fw_dir_add"
|
|
|
edc2a6 |
fi
|
|
|
c08efc |
# The list of directories is reverse-sorted in order to preserve the
|
|
|
c08efc |
# "last wins" policy in case of presence of multiple microcode
|
|
|
c08efc |
# revisions.
|
|
|
c08efc |
#
|
|
|
c08efc |
# In case of hostonly == 0, all microcode revisions will be included,
|
|
|
c08efc |
# but since the microcode search is done with the "first wins" policy
|
|
|
c08efc |
# by the (early) microcode loading code, the correct microcode revision
|
|
|
c08efc |
# still has to be picked.
|
|
|
edc2a6 |
#
|
|
|
edc2a6 |
# Note that dracut without patch [1] puts only the last directory
|
|
|
edc2a6 |
# in the early cpio; we try to address this by putting only the last
|
|
|
edc2a6 |
# matching caveat in the search path, but that workaround works only
|
|
|
edc2a6 |
# for host-only mode; non-host-only mode early cpio generation is still
|
|
|
edc2a6 |
# broken without that patch.
|
|
|
edc2a6 |
#
|
|
|
edc2a6 |
# [1] https://github.com/dracutdevs/dracut/commit/c44d2252bb4b
|
|
|
b24a43 |
done <<-EOF
|
|
|
edc2a6 |
$(find "$DATA_DIR" -maxdepth 1 -mindepth 1 -type d -printf "%f\n" \
|
|
|
edc2a6 |
| LC_ALL=C sort)
|
|
|
b24a43 |
EOF
|
|
|
b24a43 |
|
|
|
edc2a6 |
fw_dir="${fw_dir_add}${fw_dir}"
|
|
|
b24a43 |
dinfo " microcode_ctl: final fw_dir: \"${fw_dir}\""
|
|
|
b24a43 |
}
|
|
|
b24a43 |
|